Segment visitors by their session activity, then measure how that audience converted on a specific event and the revenue it drove. Audience Performance Audience Performance starts from an audience you define and reports its conversion rate and revenue. To start from a conversion event and see which channels deserve credit across the whole journey instead, use [Conversion Attribution](/docs/attribution/conversion-attribution). ## Key Features [#key-features] * **Flexible audience segmentation:** filter by UTM parameters, traffic source, location, device, browser, operating system, and pages visited in a session * **Conversion event measurement:** pick any tracked event as the conversion, with a value property for revenue * **Attribution window:** count conversions within the date range, or look back 1 to 30 days to include earlier qualifying sessions * **Six summary metrics:** Audience Size, Conversions, Converters, Conversion Rate, Avg Value per Conversion, and Total Value * **Period-over-period comparison:** prior-period trend indicators on every metric when you count within the date range * **Conversions and revenue over time:** daily, weekly, or monthly chart of conversions and revenue * **Source / Medium / Campaign breakdown:** sortable table with click-to-drill-in filtering * **Export:** CSV data (a ZIP of timeseries and breakdown files) and a multi-page PDF report For building persistent audience segments from visitor profiles for export to ad platforms, see [Audience Builder](/docs/audiences). ## Permissions [#permissions] Audience Performance uses the **Web Analytics** permission set: | Permission | Capabilities | | ------------------------ | ----------------------------------------------------------------- | | **Web Analytics: View** | View Audience Performance reports and export | | **Web Analytics: Write** | Create, edit, and delete reports (includes all View capabilities) | If you don't have the required permission, the Create, Edit, and Delete actions will be disabled. Contact your account administrator to request access. ## Creating a Report [#creating-a-report] Navigate to **Attribution Center > Audience Performance** and click **New Report**. ### Step 1: Define the Audience [#step-1-define-the-audience] Choose who counts as being in this report. **Date Range** Select the date range to analyze. The maximum is 60 days. **Audience Filters** Audience filters are optional. A visitor counts if they had at least one session matching your filters within the selected window. Audience Performance uses the same filter dimensions as Web Analytics: UTM parameters (source, medium, campaign, content, term), referrer, pages (entry, exit, or any page visited in a session), location (country, region, city), device, browser, and operating system. See [Filtering & Exporting Data](/docs/web-analytics/filtering-and-exporting#available-filter-dimensions) for the full list. Each filter supports the operators `is`, `is not`, `contains`, and `excludes`, and accepts multiple values. ### Step 2: Choose the Conversion [#step-2-choose-the-conversion] Choose which event, value field, and attribution window define a conversion for this report. **Event** Select the single event this report measures. The dropdown shows every event your website is tracking. **Value property** Choose which numeric property on the event to read as the conversion value. The default option reads each event's `value`, then `revenue`, then `amount`, using the first of those present on that event. Type a custom property name to use a different field. The value is read as a raw number and summed as-is, with no currency conversion, so make sure the property holds a clean numeric amount in a single currency. **Attribution window** Choose how conversions are matched to the audience: | Window | Description | | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | | **Within the date range** (default) | Conversions are counted inside the selected date range. | | **Custom (1 to 30 days)** | Looks back the chosen number of days before the start date, so visitors whose qualifying session fell just before the range are still included. | Results appear once you set a valid event and date range. ## Viewing Results [#viewing-results] Audience Performance report with conversion metrics, a revenue trend, and source, medium, and campaign breakdowns. ### Summary Cards [#summary-cards] Six metric cards appear in a grid: | Metric | Description | | ---------------------------- | --------------------------------------------- | | **Audience Size** | Visitors with at least one qualifying session | | **Conversions** | All matching conversion events | | **Converters** | Unique visitors who converted | | **Conversion Rate** | Converters ÷ audience size | | **Avg Value per Conversion** | Total value ÷ conversions | | **Total Value** | Summed from conversion event properties | When you count **within the date range**, each card shows a trend indicator comparing the current value against the prior period of equal length. When fewer than 30 eligible visitors match, a small-sample notice appears. Conversion rate and averages can swing widely with one or two additional events, so treat the numbers as directional until the audience grows past 30. ### Conversions and Revenue Over Time [#conversions-and-revenue-over-time] A chart of conversions and revenue across the selected date range. Conversions appear as a shaded area on the left axis and revenue as a line on the right axis. Switch the granularity between **Day**, **Week**, and **Month** to smooth out daily noise or zoom into individual days. ### Source / Medium / Campaign Breakdown [#source--medium--campaign-breakdown] A sortable table showing conversion performance by traffic source. Each converting visitor is counted once, based on their earliest qualifying session, and a totals row sums the columns. Because each converter is attributed to their earliest qualifying session, this breakdown is a first-touch view. [Conversion Attribution](/docs/attribution/conversion-attribution) can split the same conversions across every touchpoint using other models, so its source breakdown may rank channels differently for the same event and dates. | Column | Description | | ----------- | ------------------------------------------- | | Source | Traffic source (e.g., `google`, `(direct)`) | | Medium | Traffic medium (e.g., `cpc`, `(none)`) | | Campaign | Campaign name | | Conversions | Total conversion events | | Converters | Unique converting visitors | | Total Value | Summed conversion value | Sort by any column header. The table sorts by Conversions, highest first, by default. Click any value in the Source, Medium, or Campaign columns to add it as an audience filter and drill into that segment. Fallback values such as `(direct)` and `(none)` are not clickable, since there is nothing specific to filter on. A report runs on a date range of 60 days or fewer. If you select a longer range, the results panel prompts you to shorten it before the report will run. ## Exporting [#exporting] Click the **Download** button on any report to access export options. ### Export CSV Data [#export-csv-data] Downloads a ZIP file containing two CSV files: * **`timeseries.csv`**: Date, Conversions, Total Value * **`breakdown.csv`**: Source, Medium, Campaign, Conversions, Converters, Total Value ### Export PDF Report [#export-pdf-report] Downloads a multi-page PDF that includes: * A header with the report name, date range, active audience filters, conversion event, and attribution window * All six summary cards * The conversions-over-time chart * The full traffic source breakdown table The Download button is only enabled once an event and date range are selected and results have loaded. ## Saving, Sharing & Deleting [#saving-sharing--deleting] ### Saving [#saving] Select a conversion event, then click **Save** to name and persist the current report configuration: event, value property, attribution window, and audience filters. The save dialog includes a **Save date range** checkbox. Leave it checked to store the current dates with the report, or uncheck it so the report prompts for a fresh date range each time you open it. Saved reports appear on the Audience Performance list page. When you reopen a saved report, click **Save as new**, enter a different name, and the current configuration is saved as a separate report without changing the original. ### Sharing [#sharing] Click **Share** to copy the current report URL to your clipboard. The link encodes the full report configuration, so anyone with access opens it with the same settings pre-filled. ### Deleting [#deleting] From the Audience Performance list page, open the actions menu on any report and select **Delete**. Confirm the prompt to permanently remove the report. ## Next Steps [#next-steps] * **[Conversion Attribution](/docs/attribution/conversion-attribution)**: split conversion credit across a visitor's full journey with six attribution models. * **[Event Attribution Insights](/docs/attribution/event-attribution-insights)**: explore one event and the visitors behind it. * **[Audience Builder](/docs/audiences)**: build persistent audience segments for export to ad platforms. * **[Attribution FAQs](/docs/attribution/faqs)**: attribution windows, sample-size warnings, exports, and more. Conversion Attribution splits credit for a conversion event across every source, medium, and campaign that touched a visitor's journey before they converted, using whichever attribution model fits how your team thinks about credit. Conversion Attribution > **Early access.** Conversion Attribution is rolling out gradually. Contact your account representative to turn it on for your organization. Looking for conversion rates and revenue for a specific group of visitors instead? See [Audience Performance](/docs/attribution/audience-performance). Conversion Attribution answers a different question: which channels and campaigns deserve credit for conversions, across the whole visitor journey rather than just the last click. *** ## What Multi-Touch Attribution Solves [#what-multi-touch-attribution-solves] **What it is.** Most analytics tools default to last-touch reporting: a conversion gets attributed entirely to whichever source the visitor used right before converting. Multi-touch attribution instead looks at every session a visitor had in the run-up to converting, and splits credit across all of them. **Why it matters.** Last touch hides the channels that introduced or nurtured a visitor earlier in their journey. A visitor who first found you through paid social, came back twice through organic search, and converted after clicking an email link gets reported as 100% organic under last touch. Multi-touch attribution shows all three touchpoints, so budget and credit decisions reflect the full path, not just the final click. **How it works.** For each visitor who triggered your chosen conversion event, Conversion Attribution looks back across their sessions within the lookback window you select, groups them by source, medium, and campaign, and splits credit between those touchpoints according to the attribution model you choose. **Multi-touch depends on identity.** A touchpoint only earns credit if it was connected to the converting person in the first place. Sessions are resolved to a person using server-set first-party cookies, any `external_id` or `email` you send, and [Identity Recovery](/docs/identity-recovery), which is what makes a journey that starts on a phone and converts on a laptop read as one journey rather than two visitors. Every touchpoint identity resolution misses is credit silently handed to the last click. See [Visitor Identity and Matching](/docs/visitor-identity-and-matching) for how the layers fit together. Impressions count too: if you run programmatic, CTV, or audio campaigns, [view-through conversions](/docs/view-through-conversions) tracked with the impression pixel become touchpoints in these models, so ads that worked without a click are not invisible. *** ## How Each Model Splits Credit [#how-each-model-splits-credit] The model is the rule that divides one conversion's worth of credit across a visitor's touchpoints. Change the model and you change the slope of credit across the path. The conversions themselves don't change, only the story about which channels earned them. Ours Privacy gives you six models on the same first-party data, so you can see which channels hold up across all of them and which only look strong because the default model flatters them. The diagrams below use one visitor with four touchpoints, earliest to most recent. The bars show each model's shape, not exact output, since the real split also depends on how many sessions a source appears in and how far apart they fall. ### First Touch [#first-touch] All credit goes to the earliest touchpoint in the lookback window. ```text Paid social ████████████ 100% Organic · 0% Email · 0% Direct · 0% ``` **Use it when** you want to know which channels introduce people to you and you're optimizing top-of-funnel discovery. ### Last Touch [#last-touch] All credit goes to the most recent touchpoint before the conversion. ```text Paid social · 0% Organic · 0% Email · 0% Direct ████████████ 100% ``` **Use it when** you want a single channel to own each conversion, for example to compare against an ad platform's last-click report. > **Note:** Under First Touch and Last Touch, an untagged `(direct)` session never steals credit from a tagged channel. The earliest (First Touch) or latest (Last Touch) tagged session wins; `(direct)` only takes credit when every touchpoint in the path is untagged. This mirrors the "last non-direct click" behavior marketers expect from most ad and analytics tools. ### Linear [#linear] Credit is shared across the visitor's sessions, so a source seen in more sessions earns proportionally more. With four equally weighted sessions, each earns a quarter. ```text Paid social ███ 25% Organic ███ 25% Email ███ 25% Direct ███ 25% ``` Credit is split per session, not per channel. A channel that shows up in several sessions (retargeting or email, for example) accumulates more Linear credit than one touched once. That's by design, but worth keeping in mind when you compare a high-frequency channel against a low-frequency one. **Use it when** you treat every interaction as equally important and want the simplest, least opinionated multi-touch view. ### U-Shaped [#u-shaped] Position-based: the first and last touch each get 40% of the credit, and the remaining 20% is split evenly across the touchpoints in between. ```text Paid social ████████ 40% Organic ██ 10% Email ██ 10% Direct ████████ 40% ``` **Use it when** you care most about how a visitor was introduced and what closed them, while still giving the middle of the journey some credit. ### J-Shaped [#j-shaped] Position-based and back-weighted: the converting touch gets 60% of the credit, the first touch gets 20%, and the remaining 20% is split evenly across the touchpoints in between. ```text Paid social ████ 20% Organic ██ 10% Email ██ 10% Direct ████████████ 60% ``` J-Shaped sits between U-Shaped and Last Touch. It agrees with Last Touch that the session which closed the deal did the most work, but unlike Last Touch it still credits the channel that started the journey with a real share rather than nothing. **Use it when** your sales motion is closing-heavy and you want the converting channel to dominate, without erasing the channel that created the demand. ### Time Decay [#time-decay] Touchpoints closer to the conversion earn more credit. Each touchpoint's weight halves every 7 days further back from the conversion, then the weights are scaled so the visitor's credit still sums to one conversion. In practice, a touch the day before converting is worth about double one from a week earlier, and roughly four times one from two weeks earlier. ```text Paid social ██ least credit (oldest) Organic ███ Email █████ Direct ████████ most credit (most recent) ``` **Use it when** recency matters and the touches nearest the conversion did the most work, common for shorter consideration cycles and retargeting-heavy programs. ### Choosing a Model [#choosing-a-model] There's no single correct model. The honest approach is to read your conversions under more than one. Start with **Last Touch** to match what your ad platforms report, then switch to **First Touch** to see which channels they quietly undersell. Use **Linear** as a neutral baseline, **U-Shaped** when your team thinks in terms of "what opened and what closed," **J-Shaped** when closing deserves most of the credit but discovery still deserves some, and **Time Decay** when recent touches genuinely matter more. A channel that ranks high across several models is doing real work at every stage; one that only ranks high under Last Touch may be harvesting demand that other channels created. ### A Worked Example [#a-worked-example] Say one visitor converts on `appointment_booked` after four sessions inside the lookback window: 1. Paid social, about 21 days before converting 2. Organic search, about 14 days before 3. Organic search, about 7 days before 4. Email, the day before That one conversion splits very differently depending on the model: | Channel | First Touch | Last Touch | Linear | U-Shaped | J-Shaped | Time Decay | | -------------- | ----------- | ---------- | ------ | -------- | -------- | ---------- | | Paid social | 100% | 0% | 25% | 40% | 20% | 7% | | Organic search | 0% | 0% | 50% | 20% | 20% | 42% | | Email | 0% | 100% | 25% | 40% | 60% | 51% | Reading across one row tells the story. Paid social introduced this visitor and owns the whole conversion under First Touch, but barely registers under Time Decay. Organic search never wins a single-touch model, yet earns the most credit under Linear because it appears in two of the four sessions. Email closes the visitor and dominates the recency-weighted view, and under J-Shaped it takes 60% while paid social still keeps a fifth of the credit. Same conversion, six defensible stories. (Values are illustrative; the real split depends on how many sessions each source appears in and how far apart they fall.) *** ## Permissions [#permissions] Conversion Attribution uses the **Web Analytics** permission set: | Permission | Capabilities | | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- | | **Web Analytics: View** | View Conversion Attribution reports: change the conversion event, attribution model, lookback window, and audience filters, and export results | | **Web Analytics: Write** | All View capabilities, plus saving an audience filter combination as a reusable segment | If you don't have the required permission, ask your account administrator to grant Web Analytics access. *** ## Building a Report [#building-a-report] Navigate to **Attribution Center > Conversion Attribution**. ### Step 1: Choose the Conversion Event and Date Range [#step-1-choose-the-conversion-event-and-date-range] Pick the event that counts as a conversion from the dropdown, which lists every event your website is tracking. Then select a date range of up to 31 days. The date range is capped at 31 days. Ranges longer than that aren't supported. ### Step 2: Choose an Attribution Model [#step-2-choose-an-attribution-model] The attribution model controls how credit for a conversion is split across a visitor's touchpoints: | Model | How it splits credit | | --------------- | --------------------------------------------------------------------------------------------------------------- | | **First Touch** | All credit to the earliest session in the lookback window | | **Last Touch** | All credit to the most recent session before the conversion | | **Linear** | Credit shared across the visitor's sessions, so a source seen in more sessions earns proportionally more | | **U-Shaped** | 40% to the first touch, 40% to the last touch, the remaining 20% split across everything in between | | **J-Shaped** | 60% to the last touch, 20% to the first touch, the remaining 20% split across everything in between | | **Time Decay** | Credit weighted toward recency, with each touchpoint's weight halving every 7 days the further back it occurred | First Touch and Last Touch give all credit to a single session. Linear, U-Shaped, J-Shaped, and Time Decay are true multi-touch models that spread credit across multiple sessions in the same path. See [How Each Model Splits Credit](#how-each-model-splits-credit) above for how each one reshapes the same journey and when to choose it. ### Step 3: Choose a Lookback Window [#step-3-choose-a-lookback-window] The lookback window sets how far back Conversion Attribution looks for a visitor's sessions before their conversion. Choose 7, 14, 30, or 60 days. A shorter window favors recent, bottom-of-funnel touchpoints; a longer window surfaces channels that introduced the visitor further in advance. ### Step 4: Narrow with Audience Filters (Optional) [#step-4-narrow-with-audience-filters-optional] Add audience filters to scope the report to a subset of visitors, the same filter dimensions available in Web Analytics: UTM source, medium, campaign, content, and term, referrer, country, region, city, device, browser, operating system, and entry or exit page. You can also scope the report to a single web source. Filtering by a specific page URL isn't supported for Conversion Attribution (entry page and exit page filters still work). Use [Audience Performance](/docs/attribution/audience-performance) or Web Analytics if you need to filter by page. If you have **Web Analytics: Write** access, save your filter combination as a segment to reuse it in future reports. *** ## Viewing Results [#viewing-results] Conversion Attribution report with the selected multi-touch model, top touchpoints, and source, medium, and campaign credit table. ### Audience Contribution [#audience-contribution] When you scope the report with audience filters or a web source, a summary card shows what share of all conversions for the chosen event came from that scoped audience. ### Top Touchpoints [#top-touchpoints] A chart of the five sources with the highest attributed credit, ranked by their share of total attributed conversions. Expand a row in the table below to see the medium and campaign behind a source. ### Top Combo [#top-combo] A card calling out the single highest-credit source, medium, and campaign combination, with its conversion credit, its share of the total, and the number of sessions behind it. A real UTM combination is preferred over `(direct)` for this card, so untagged traffic only takes the top spot when every path is untagged. ### Source / Medium / Campaign Table [#source--medium--campaign-table] A hierarchical table breaking down attributed conversions by source, medium, and campaign: | Column | Description | | ----------- | -------------------------------------------------------------------- | | Source | Traffic source (e.g., `google`, `(direct)`) | | Medium | Traffic medium (e.g., `cpc`, `(none)`) | | Campaign | Campaign name | | Sessions | Sessions counted toward this path | | Conversions | Attributed conversion credit for this path, under the selected model | | Share % | This path's share of total attributed conversions | Rows nest by UTM dimension: source, then medium, then campaign. Expand or collapse a row to drill into the next level, or use **Expand all** to open the full hierarchy. Sort by UTM path, sessions, or conversions. Conversions default to highest first. Because Linear, U-Shaped, J-Shaped, and Time Decay split one conversion across the touchpoints in a path, per-path conversion values can be fractional and do not sum to the converter total. First Touch and Last Touch award the whole conversion to one path. Untagged sessions are grouped under `(direct)` and earn credit like any other touchpoint. The preference rule applies only to the single-credit models: with First Touch or Last Touch, a tagged source is preferred over `(direct)` when both occur at the same point in a path, and `(direct)` only takes the top spot when every touchpoint in the path is untagged. Under Linear, U-Shaped, J-Shaped, and Time Decay there is no tie to break, so `(direct)` is treated as an ordinary bucket and can rank at the top when enough sessions are untagged. *** ## Exporting [#exporting] Click **Export CSV** to download the source, medium, campaign, sessions, conversions, and share percentage for every row in the table. *** ## Next Steps [#next-steps] * **[Audience Performance](/docs/attribution/audience-performance)**: measure conversion rate and revenue for an audience you define. * **[Event Attribution Insights](/docs/attribution/event-attribution-insights)**: explore one event and the visitors behind it. * **[Attribution FAQs](/docs/attribution/faqs)**: attribution models, lookback windows, exports, and more. Conversion Journey Summary traces how visitors reach a conversion. For a conversion event you choose, it summarizes the sources, timing, touchpoints, and page flow behind the people who converted. Conversion Journey Summary > **Early access.** Conversion Journey Summary is part of Journeys, which is rolling out gradually. Contact your account representative to turn it on for your organization. Want conversion credit split across every touchpoint using models like Linear or Time Decay? Use [Conversion Attribution](/docs/attribution/conversion-attribution). Conversion Journey Summary answers a different question: what did the journeys of the people who converted actually look like, from first touch to conversion? *** ## What It Shows [#what-it-shows] Pick a conversion event and Conversion Journey Summary describes the visitors who completed it: how many converted, how long their journeys took, how many touchpoints they had, which traffic sources started and closed those journeys, the most common ordered source paths, and the page flow that led into the conversion. *** ## Permissions [#permissions] Conversion Journey Summary uses the **Web Analytics** permission set: | Permission | Capabilities | | ------------------------ | ----------------------------------------------------------------------------------------------------------- | | **Web Analytics: View** | Build and read a summary: change the conversion event, attribution window, date range, and audience filters | | **Web Analytics: Write** | All View capabilities, plus saving a filter combination as a reusable segment | If you don't have the required permission, ask your account administrator to grant Web Analytics access. *** ## Building a Report [#building-a-report] Navigate to **Attribution Center > Conversion Journey Summary**. ### Step 1: Choose the Conversion Event [#step-1-choose-the-conversion-event] Select the event that counts as a conversion from the **Conversion event** dropdown. The list includes the events eligible as conversion goals and excludes high-volume automatic behaviors like page views, clicks, and scrolls. ### Step 2: Choose an Attribution Window [#step-2-choose-an-attribution-window] The **Attribution window** sets how far back a journey's first touch is counted before the conversion. Choose 7, 14, 30, 60, or 90 days. A shorter window keeps the focus on recent touchpoints; a longer window captures journeys that started further in advance. ### Step 3: Set the Date Range and Audience [#step-3-set-the-date-range-and-audience] Choose a **date range** of up to 60 days for the conversions you want to summarize. Use the **Filter** button to scope the report to a subset of visitors with the audience filters available across Web Analytics: UTM parameters, traffic source, location, device, browser, and more. You can select a single web source and toggle whether bots are excluded, and, with Write access, save a filter combination as a segment. ### Step 4: Share a Summary [#step-4-share-a-summary] Every selection is captured in the page URL, so you can click **Share** to copy a link that reopens the same summary for a teammate. *** ## Viewing Results [#viewing-results] Conversion Journey Summary showing conversion metrics, source paths, page paths, and journey timing. ### Summary Cards [#summary-cards] Four cards summarize the converters over the selected range: | Card | Description | | ------------------------ | ----------------------------------------------------------------- | | **Converters** | Unique visitors who converted | | **Avg. time to convert** | Average time from first touch to conversion, within the window | | **Avg. touchpoints** | Average number of touchpoints before converting | | **Top entry source** | The leading first-touch source and its share of all first touches | ### Top Source Paths to Conversion [#top-source-paths-to-conversion] The ordered sequence of traffic sources each converter touched on the way to converting, with consecutive repeats of the same source merged into one. Each row shows the path as a series of source labels ending in the conversion, the number of converters who followed it, and its share of all converters. Less-common paths roll up into a single row so the most common routes stay readable. ### Page Paths Before Conversion [#page-paths-before-conversion] A flow diagram that reads from the conversion backward: the page visitors were on just before converting, then the page before that, and so on. Ribbons are colored by traffic source, and a legend maps each color to its source. Hover a page or ribbon for a quick breakdown of converters and the sources behind it, or click one to open the full source, medium, and campaign drill-down. ### Time, Touchpoints, and Touch Sources [#time-touchpoints-and-touch-sources] Below the flow diagram, four panels break the journeys down further: * **Time to conversion**: distribution of how many days journeys took, from first touch to conversion. * **Touchpoints to conversion**: distribution of how many touchpoints journeys had before converting. * **First-touch source**: ranked list of the sources that started the journeys. Click a source for its medium and campaign breakdown. * **Last-touch source**: ranked list of the sources of the converting session. Click a source for its medium and campaign breakdown. ### Source Drill-Downs [#source-drill-downs] Click any source in the first-touch or last-touch lists, or any node in the page flow, to open a breakdown table of converters by source, medium, and campaign. The table sorts by any column and includes an **Other** roll-up row and a **Total** row. Sources are grouped by their `utm_source` value rather than mapped into named marketing channels, so the labels match the UTMs you tag your links with. Untagged traffic is grouped under `(direct)`. *** ## When to Use This Tool [#when-to-use-this-tool] Reach for Conversion Journey Summary when you want the shape of the journeys behind a conversion: how long they took, how many touchpoints they had, and which sources and pages led into them. When you need conversion credit split across touchpoints using a specific model, use [Conversion Attribution](/docs/attribution/conversion-attribution). When you want to walk paths step by step without anchoring on a conversion, use [Journey Explorer](/docs/attribution/journey-explorer). *** ## Next Steps [#next-steps] * **[Journey Explorer](/docs/attribution/journey-explorer)**: walk the paths visitors take, one step at a time. * **[Conversion Attribution](/docs/attribution/conversion-attribution)**: full-journey multi-touch credit across six attribution models. * **[Attribution FAQs](/docs/attribution/faqs)**: attribution models, date-range limits, exports, and more. Event Attribution Insights is the fastest way to explore which sources, campaigns, and touchpoints contributed to a single conversion event, down to the individual visitors who converted. Event Attribution Insights Want credit split across every touchpoint in a journey using models like Linear or Time Decay? Use [Conversion Attribution](/docs/attribution/conversion-attribution). Event Attribution Insights is a lighter-weight, single-model view focused on exploring one event and the visitors behind it. *** ## What It Shows [#what-it-shows] Pick a conversion event and Event Attribution Insights surfaces how many times it happened, how it trended over time, who triggered it, and which traffic sources brought those visitors in. It's a diagnostic tool: start broad, then narrow with UTM filters to test a hypothesis about a specific channel or campaign. *** ## Building a Report [#building-a-report] Navigate to **Attribution Center > Event Attribution Insights**. ### Step 1: Choose the Conversion Event and Date Range [#step-1-choose-the-conversion-event-and-date-range] Select the event you want to analyze from the dropdown, which lists every event your website is tracking. Then choose a date range of up to 60 days. ### Step 2: Choose an Attribution Model [#step-2-choose-an-attribution-model] Pick how credit is assigned to a visitor's touchpoints: | Model | How it assigns credit | | --------------- | -------------------------------------------------- | | **First Touch** | The visitor's earliest session | | **Last Touch** | The visitor's most recent session before the event | For credit spread across multiple touchpoints in a journey, use [Conversion Attribution](/docs/attribution/conversion-attribution) instead. ### Step 3: Filter by UTM Parameters (Optional) [#step-3-filter-by-utm-parameters-optional] Open the **UTM Parameters** section to narrow the report to a specific channel or campaign with any combination of six UTM filters: source, campaign, medium, content, term, and name. Each filter autocompletes against the values seen for the selected event and date range, and you can type a custom value if you don't see the one you want. The attribution model selector also lives in this section, so you can switch between First Touch and Last Touch alongside your filters. *** ## Viewing Results [#viewing-results] Event Attribution Insights for a conversion event with summary metrics, event timeline, visitor list, and source breakdown. ### Summary Cards [#summary-cards] Four cards summarize the event over the selected range: | Metric | Description | | ------------------------ | ----------------------------------------- | | **Total Events** | All occurrences of the event | | **Average Daily Events** | Total events divided by days in range | | **Peak Day Events** | The single busiest day's count | | **Unique Visitors** | Distinct visitors who triggered the event | ### Event Timeline [#event-timeline] A chart of event count by day, so you can spot trends, spikes, and quiet periods across the range. ### Matching Visitors [#matching-visitors] A list of the visitors who triggered the event. Each row shows the visitor with their avatar and name and when they were last seen, and links to that visitor's full profile. The list loads 25 visitors at a time; click **Load More** to page through the rest. ### Entry Pages and Source Breakdown [#entry-pages-and-source-breakdown] An entry pages table breaks the converting visitors down by the page they landed on. Below it, two side-by-side source tables show traffic source and a last-touch view, so you can see where this event's audience came from. All three tables respect your selected attribution model and UTM filters. ### Session Replays [#session-replays] Up to 10 recent session replays for the event appear at the bottom of the report. If you have [Session Replay](/docs/session-replay) recording enabled, you can watch the actual sessions behind the numbers. *** ## When to Use This Tool [#when-to-use-this-tool] Reach for Event Attribution Insights when you want a quick, visitor-level look at one event and the channels behind it. Step up to [Conversion Attribution](/docs/attribution/conversion-attribution) when you need multi-touch credit split across a full journey, or [UTM Performance Comparison](/docs/attribution/utm-performance-comparison) when you want to put several UTM combinations side by side. *** ## Next Steps [#next-steps] * **[Conversion Attribution](/docs/attribution/conversion-attribution)**: full-journey multi-touch credit across six attribution models. * **[UTM Performance Comparison](/docs/attribution/utm-performance-comparison)**: compare specific UTM combinations head to head. * **[Attribution FAQs](/docs/attribution/faqs)**: attribution models, date-range limits, exports, and more. Common questions about the Attribution Center. New to attribution? Start with the [overview](/docs/attribution). For questions specific to funnels, see the [Funnels FAQs](/docs/attribution/funnels#faqs). *** ## General [#general] ### Which tool should I use for multi-touch attribution? [#which-tool-should-i-use-for-multi-touch-attribution] > [Conversion Attribution](/docs/attribution/conversion-attribution). It splits credit for a conversion across every touchpoint in the journey, using models like Linear, U-Shaped, J-Shaped, and Time Decay. [Event Attribution Insights](/docs/attribution/event-attribution-insights) is a lighter, single-model view of one event. ### Why don't these numbers match my ad platform's reporting? [#why-dont-these-numbers-match-my-ad-platforms-reporting] > Ad platforms credit themselves, using their own attribution windows and cookies. Ours Privacy attributes from your own first-party event data, so it reads as an independent source of truth rather than a copy of any one platform's view. ### Do the attribution tools use third-party cookies? [#do-the-attribution-tools-use-third-party-cookies] > No. Attribution runs on the same first-party event data as the rest of your analytics, so it keeps working as third-party cookies go away. ### Do the attribution tools reconcile with each other and with Web Analytics? [#do-the-attribution-tools-reconcile-with-each-other-and-with-web-analytics] > They read the same underlying events, but each tool reports a purpose-built metric, so the headline totals are not meant to match number for number. Conversion Attribution splits one conversion into fractional credit across touchpoints; UTM Performance Comparison reports events per visitor (which can read above 100%); Audience Performance counts each converter once on their earliest session; Event Attribution Insights counts every occurrence of the event. The events behind them line up across [Web Analytics](/docs/web-analytics), [Funnels](/docs/attribution/funnels), and the Attribution Center; the metrics differ because each answers a different question. ### What are the date-range and lookback limits for each tool? [#what-are-the-date-range-and-lookback-limits-for-each-tool] > Event Attribution Insights and Audience Performance allow date ranges up to 60 days. Conversion Attribution and UTM Performance Comparison cap the range at 31 days. To look back beyond the report dates, Conversion Attribution offers a lookback window of 7, 14, 30, or 60 days, and Audience Performance offers an attribution window of either "within the date range" or a custom 1 to 30 days. The lookback window and the attribution window do the same kind of job (pulling in earlier qualifying sessions) but are named and capped differently in each tool. ### Where do I see revenue, not just conversions? [#where-do-i-see-revenue-not-just-conversions] > [Audience Performance](/docs/attribution/audience-performance) reports revenue and average value alongside conversion rate. The other tools focus on conversion counts and credit. ### Is attribution HIPAA-compliant? [#is-attribution-hipaa-compliant] > Ours Privacy is built for HIPAA-regulated workflows, with no separate BAA or compliance add-on required. As always, compliance also depends on how you configure tracking and consent. ### Does attribution work on mobile app events? [#does-attribution-work-on-mobile-app-events] > First-touch and last-touch attribution do. Multi-touch [Conversion Attribution](/docs/attribution/conversion-attribution) does not, because it splits credit across sessions and a session is built from web page views. A visitor with app events only has no sessions to split credit across. See [Mobile App Attribution](/docs/mobile-app-attribution) for what an app setup does and does not measure. *** ## Event Attribution Insights [#event-attribution-insights] ### How is Event Attribution Insights different from Conversion Attribution? [#how-is-event-attribution-insights-different-from-conversion-attribution] > Event Attribution Insights gives each visitor's credit to a single session (First Touch or Last Touch) and is built for fast, visitor-level exploration of one event. [Conversion Attribution](/docs/attribution/conversion-attribution) splits credit across every touchpoint in the journey using six models. ### Why don't I see a visitor I expect in the list? [#why-dont-i-see-a-visitor-i-expect-in-the-list] > The matching-visitors list loads 25 at a time. Click **Load More** to page through the rest. ### Can I export the results? [#can-i-export-the-results] > There's no file export. The report is interactive, and its configuration lives in the URL, so you can bookmark or share a link to return to the same view. *** ## Conversion Attribution [#conversion-attribution] ### How is Conversion Attribution different from Audience Performance? [#how-is-conversion-attribution-different-from-audience-performance] > Audience Performance measures conversion rate and revenue for a segment of visitors you define. Conversion Attribution answers a different question: of all the conversions for one event, which sources, mediums, and campaigns deserve credit, across a visitor's full journey rather than just their last session. ### Which attribution model should I use? [#which-attribution-model-should-i-use] > Use First Touch or Last Touch when you want a single channel to own each conversion (for example, comparing against a last-click report from an ad platform). Use Linear, U-Shaped, J-Shaped, or Time Decay when you want credit spread across the channels that contributed along the way. U-Shaped works well when you care most about how a visitor was introduced and what closed them; J-Shaped when the closing touch should dominate but the first touch still deserves a real share; Time Decay works well when recent touches should count more than early ones. ### Why don't I see a converter if they exist in my account? [#why-dont-i-see-a-converter-if-they-exist-in-my-account] > A conversion only earns attributed credit if the visitor had at least one tracked session within the lookback window before they converted. If none of an event's converters have an eligible session in that window, the report shows an empty state suggesting a longer lookback. Widen the lookback window to capture earlier sessions. ### What's the maximum date range and lookback window? [#whats-the-maximum-date-range-and-lookback-window] > The date range is capped at 31 days. The lookback window is a dropdown of 7, 14, 30, or 60 days. ### Why is my attributed conversion total lower than my actual conversion count? [#why-is-my-attributed-conversion-total-lower-than-my-actual-conversion-count] > A conversion only earns attributed credit when the converter had at least one tracked session within the lookback window. Converters with no eligible session in that window are not attributed, so the attributed total can come in below the raw number of conversions for the event. Widen the lookback window to bring more of those journeys into the report. ### Can I save a Conversion Attribution report? [#can-i-save-a-conversion-attribution-report] > Conversion Attribution reports aren't saved as named reports. Configuration (event, model, lookback window, filters) lives in the URL, so you can bookmark or share a link to return to the same view. If you need a persisted, shareable report, use [Audience Performance](/docs/attribution/audience-performance) instead. *** ## UTM Performance Comparison [#utm-performance-comparison] ### How many comparisons can I add? [#how-many-comparisons-can-i-add] > Up to five at a time. ### Why is my conversion rate above 100%? [#why-is-my-conversion-rate-above-100] > The **Conv Rate** column is total events divided by visitors, so it climbs above 100% when visitors trigger the event more than once. Read it as events per visitor rather than a funnel completion rate. ### Will my comparisons still be there when I come back? [#will-my-comparisons-still-be-there-when-i-come-back] > Yes. Comparisons are saved in your browser for the organization you're viewing. They won't follow you to a different browser or device. ### Can I export the table? [#can-i-export-the-table] > Yes. Use the **Export** button in the page header to download the comparison table as a ZIP of CSV files. ### How is this different from Conversion Attribution? [#how-is-this-different-from-conversion-attribution] > UTM Performance Comparison measures fixed campaigns you choose, side by side. [Conversion Attribution](/docs/attribution/conversion-attribution) automatically splits credit across every touchpoint in a visitor's journey, no manual combinations required. *** ## Audience Performance [#audience-performance] ### What counts as being "in the audience"? [#what-counts-as-being-in-the-audience] > A visitor is included if they had at least one session matching your audience filters within the selected date range. In lookback mode, qualifying sessions may also fall before the range start date if they are within the lookback window. ### What is the attribution window? [#what-is-the-attribution-window] > The attribution window controls how conversions are matched to your audience. "Within date range" counts conversions that occur inside the selected dates. A 1–30 day lookback extends the audience window backward from the start date, capturing visitors who first engaged before the reporting period. ### Why is the Download button disabled? [#why-is-the-download-button-disabled] > Set an event and date range, run the report, then the Download button enables. ### What does the small-sample warning mean? [#what-does-the-small-sample-warning-mean] > Fewer than 30 visitors matched the audience. Conversion rate and averages can shift with one or two events. Treat them as directional until the audience grows. ### What is the maximum date range for a report? [#what-is-the-maximum-date-range-for-a-report] > 60 days. If you pick a longer range, the report prompts you to choose 60 days or fewer. ### Who can create and edit reports? [#who-can-create-and-edit-reports] > Users with **Web Analytics: Write** access can create, edit, and delete reports. Users with **Web Analytics: View** access can open and export reports but cannot make changes. *** ## Need Help? [#need-help] If your question isn't covered here, reach out to [support@oursprivacy.com](mailto:support@oursprivacy.com). Use Funnels to see how visitors move through a series of steps on your website, measure the conversion rate at each step, and find where they drop off. Funnels are session-based: they track a visitor's progression through the steps within a single browsing session. Funnels Whether you are tracking a patient intake flow, an appointment booking process, or a content engagement path, a funnel shows you exactly where visitors convert and where they leave, so you can focus on the steps that matter most. *** ## Permissions [#permissions] Funnels uses the Web Analytics permission set. | Permission | Capabilities | | -------------------- | ----------------------------------------------------------------- | | Web Analytics: View | View funnel analytics, browse the funnels list, and export PDFs | | Web Analytics: Write | Create, edit, and delete funnels (includes all View capabilities) | If you do not have Write access, you can view funnel analytics but cannot change funnel configuration. Ask your account administrator for Web Analytics: Write access. *** ## Create a funnel [#create-a-funnel] Open **Funnels** from the Analytics section of the left navigation, then click **Create Funnel**. ### Name the funnel [#name-the-funnel] Give the funnel a descriptive name that identifies the journey you are tracking, such as "Appointment Booking Flow" or "Blog to Contact Form." ### Define the steps [#define-the-steps] A funnel needs between 2 and 10 steps. Each step represents an action a visitor must take to continue through the funnel. There are two step types: | Step type | Matches when a visitor... | Example | | ----------- | ---------------------------------- | -------------------------------- | | Viewed page | Views a specific page, or any page | Page is `/appointments/schedule` | | Event | Triggers a specific tracked event | Event is `form_submit` | For a **Viewed page** step, select a pathname from the dropdown (your top pages from the last 60 days) or leave it blank to match any page view, which works well as a broad entry point. You can also type a custom pathname. For an **Event** step, pick from the list of event names. The dropdown combines your allowed events with events tracked in the last 60 days. To reorder steps, drag them by the handle on the left. The funnel measures progression in the order you set. ### Add step filters [#add-step-filters] Each step supports optional filters that narrow what counts as a match. Open a step for editing and add conditions under **Where**. Available filter properties include: * **Page:** pathname, current URL, and page title * **UTM:** source, medium, campaign, content, and term * **Traffic source:** referrer and referring domain * **Location:** country, state, and city * **Browser and device:** browser, operating system, device type, and is-bot * **Event properties:** any custom property sent with the event Each condition has a property, an operator (is, is not, contains, does not contain, starts with, ends with, is greater than, is less than, is null, is not null), and a value. You can add up to 10 conditions per step, and all of them must match (AND logic). UTM filters offer autocomplete suggestions based on values seen in the last 60 days. ### Configure funnel settings [#configure-funnel-settings] Below the steps, configure how the funnel behaves. #### Counting method [#counting-method] Choose how visitors are counted across funnel entries. | Method | Counts | | ------------------ | ------------------------------------------------------------------------ | | Sessions (default) | Each qualifying browser session as an independent funnel attempt | | Uniques | Each visitor once, deduplicated by visitor | | Totals | Every matching event, so one visitor can contribute multiple completions | #### Step order [#step-order] Choose whether steps must occur in the order you defined. | Order | Behavior | | --------------- | ---------------------------------------------------------------------------- | | Exact (default) | Steps must occur in sequence. Step 2 only counts if it follows Step 1 | | Any order | Steps can occur in any order within the session, useful for non-linear flows | #### Conversion window [#conversion-window] The conversion window limits how long a visitor has to complete the whole funnel from the first step. Turn it on, then set a value and a unit (minutes, hours, or days). If a visitor does not complete every step within the window, the later steps are not counted. The window is off by default, in which case there is no time limit within a session. #### Funnel change notifications [#funnel-change-notifications] Use **Watch this funnel** if you want optional notifications for meaningful changes in funnel performance. When enabled, Ours Privacy sends a notification if a step's conversion rate moves beyond its expected range. Funnel notifications follow your [notification preferences](/docs/notification-preferences) for email and in-app delivery. If your organization uses shared Slack notifications, an admin can also route funnel notifications to a Slack channel from [Notification channels](/docs/slack-notifications). This setting does not change analytics. You can turn it on or off later from the edit page. ### Save [#save] Click **Save funnel**. Results are calculated when you open the funnel, so analytics are available right away — there is no waiting period after saving. A funnel needs a name and at least two valid steps before it can be saved. *** ## View funnel analytics [#view-funnel-analytics] Open a funnel from the funnels list to view its results. Ready funnel analytics showing step conversion rates, drop-off, and the funnel summary table. ### Summary metrics [#summary-metrics] At the top of the page you see two metrics: * **Overall conversion** is the percentage of visitors who completed every step in the funnel. * **Avg time to conversion** is the average time for a visitor to go from the first step to the last. ### Funnel visualization [#funnel-visualization] The funnel chart shows a horizontal bar for each step. A solid bar shows the share of visitors who reached that step, and a lighter bar shows the share that dropped off before it. Each bar carries its conversion percentage, and below it the chart lists how many visitors reached the step and how many dropped off, each with its rate. This makes it easy to spot the biggest drop-offs in your flow. ### Funnel summary [#funnel-summary] Below the chart, a table breaks down each step transition. | Column | Description | | ------------------ | ------------------------------------------------------------------------------------------ | | Step | The pair of steps being measured (for example, Step 1 to Step 2) | | Conversion Rate | Percentage of visitors from the previous step who reached the next, with the visitor count | | Drop off | Percentage who did not continue, with the visitor count | | Time to conversion | Average time between the two steps | An **Overall** row summarizes the full funnel from the first step to the last. ### Date range [#date-range] Use the date range picker to view performance over different periods. You can select any range up to 31 days, so a full calendar month fits. *** ## Watch session replays [#watch-session-replays] Click **Watch** next to a step's reached or dropped-off count to open the Session Replays panel. * Use **Watch** on a **reached** count to see sessions that moved on to that step. * Use **Watch** on a **dropped off** count to see sessions that left the funnel there. The panel shows a sample of up to 50 recent sessions, each with its timestamp and duration, so you can see what visitors actually experienced at each stage. Session replays appear in Funnels only when Session Replay is enabled on your account. See [Session Replay](/docs/session-replay) for setup details. *** ## Export to PDF [#export-to-pdf] Click **Download PDF** on a funnel analytics page to generate a report that includes: * Funnel name and date range * Active funnel settings (counting method, step order, and conversion window) * Per-step filter conditions shown as compact badges * Overall conversion and average time to conversion * The funnel visualization * The funnel summary table, including the Overall row The report is ready to share with stakeholders or attach to internal reviews. *** ## Edit and delete funnels [#edit-and-delete-funnels] To edit a funnel, open it from the funnels list and click **Edit**. You can rename it, add or remove steps, reorder steps, change step filters, and adjust the funnel settings. Saving changes to steps, filters, conversion window, counting method, or step order applies immediately — the next time you open the funnel, results reflect the updated configuration. To delete a funnel, open the actions menu on the funnels list and select **Delete**. You are asked to confirm before the funnel is permanently removed. *** ## FAQs [#faqs] **How many steps can a funnel have?** > Between 2 and 10 steps. **How long does it take for results to appear?** > Results are calculated when you open the funnel, so they are available immediately after saving. Larger accounts and wider date ranges take longer to load. **What does session-based mean?** > A session-based funnel tracks a visitor's progression through the steps within a single browsing session. If a visitor completes Step 1 in one session and Step 2 in a different session, it counts as a drop-off after Step 1. **Can I add filters to individual steps?** > Yes. Each step supports property-based conditions, such as a pathname or a UTM source. Open a step for editing and add conditions under Where. All conditions on a step must match for the step to count. **What is the conversion window?** > The conversion window limits how long a visitor has to complete the whole funnel from the first step. For example, a 30-minute window means every step must be completed within 30 minutes of the first. When it is off, there is no time limit within a session. **Can funnels send change notifications?** > Yes. You can enable optional notifications for meaningful conversion-rate drops or spikes at a funnel step. Personal email and in-app delivery follow your notification preferences. Shared Slack delivery is controlled separately by your organization's notification channel settings. **What is the difference between the counting methods?** > Sessions (the default) counts each browser session as an independent funnel attempt. Uniques deduplicates by visitor and counts each person once. Totals counts every matching event occurrence. **What happens if I change my funnel steps or settings?** > The change applies immediately. Because results are calculated when you open the funnel, the next view reflects the new configuration. Changing only notification delivery does not affect analytics. **Who can create and edit funnels?** > Users with Web Analytics: Write access can create, edit, and delete funnels. Users with view-only access can see funnel analytics and export PDFs but cannot make changes. *** ## Next Steps [#next-steps] * [Attribution Center overview](/docs/attribution) * [Audience Performance](/docs/attribution/audience-performance) * [Session Replay](/docs/session-replay) Attribution is one place to measure how your marketing drives conversions: which channels get credit, which campaigns perform, and how much revenue your visitors generate. It's a single suite built on one dataset. You look at that data several ways depending on the question you're asking: by event, by full-journey credit, by campaign, by audience, and by funnel step. This page helps you pick the right view in a few seconds. Attribution Center > **Looking for multi-touch attribution?** [Conversion Attribution](/docs/attribution/conversion-attribution) ships six models on your own first-party data: **First Touch, Last Touch, Linear, U-Shaped, J-Shaped, and Time Decay**, with lookback windows up to 60 days. [How each model splits credit](/docs/attribution/conversion-attribution#how-each-model-splits-credit) walks through the differences with a worked example. > **Tracking healthcare events?** Adopt the [Standard Healthcare Events](/docs/standard-healthcare-events) schema and attribution gets easier. Because events like `appointment_booked` and `revenue_recognized` are recognized automatically, conversion and revenue reporting work without mapping each event by hand. *** ## Why Ours Privacy Attribution [#why-ours-privacy-attribution] * **Built on your own first-party data.** Attribution is computed from the events you track with Ours Privacy, not modeled or sampled from an ad platform's reporting. The numbers are yours, end to end. * **HIPAA-compliant by default.** Built for regulated workflows, with no separate BAA or compliance add-on required. * **No third-party cookies required.** Visitor journeys are stitched from first-party data, so attribution keeps working as third-party cookies go away. * **Multi-touch across devices, not just sessions.** Touchpoints are resolved to a person, so a journey that starts on a phone and converts on a laptop is one journey. See [Visitor Identity and Matching](/docs/visitor-identity-and-matching). * **Six attribution models on the same data.** Read one conversion under First Touch, Last Touch, Linear, U-Shaped, J-Shaped, and Time Decay to see which channels hold up and which only look strong under the default. * **One dataset, many lenses.** Every view here, plus [Web Analytics](/docs/web-analytics), reads the same tracked events, so your reports reconcile instead of telling different stories. *** ## Which View Answers Your Question? [#which-view-answers-your-question] | If you want to… | View | It answers | | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | --------------------------------------------------------------------------- | | Explore one conversion event and see who converted and where they came from | **[Event Attribution Insights](/docs/attribution/event-attribution-insights)** | "Who converted, and what channel brought them in?" | | Split credit for one conversion event across every touchpoint in the journey | **[Conversion Attribution](/docs/attribution/conversion-attribution)** | "Which channels deserve credit, across the whole journey?" | | Compare specific campaigns or UTM combinations side by side | **[UTM Performance Comparison](/docs/attribution/utm-performance-comparison)** | "How do these campaigns stack up against each other?" | | Measure how a defined audience converted and what revenue it drove | **[Audience Performance](/docs/attribution/audience-performance)** | "How well did this audience convert, and what did it earn?" | | See where visitors drop off across an ordered sequence of steps | **[Funnels](/docs/attribution/funnels)** | "Where in my flow do people fall out?" | | Walk the paths visitors take through your site, one step at a time | **[Journey Explorer](/docs/attribution/journey-explorer)** | "Once someone did this, where did they go next?" | | Summarize the sources, timing, and pages behind a conversion event | **[Conversion Journey Summary](/docs/attribution/conversion-journey-summary)** | "What did the journeys of the people who converted look like?" | | Understand what can and cannot be measured in a mobile app | **[Mobile App Attribution](/docs/mobile-app-attribution)** | "What do we get from our app, and do we need a mobile measurement partner?" | Attribution Center showing the available conversion, journey, campaign, audience, and funnel reporting views. *** ## The Views [#the-views] ### Event Attribution Insights [#event-attribution-insights] [Event Attribution Insights](/docs/attribution/event-attribution-insights) zooms in on a single conversion event and the visitors behind it: how the event trends over time, who triggered it, which pages they entered on, and which sources brought them in. A fast, visitor-level diagnostic with first-touch or last-touch attribution and UTM filtering. ### Conversion Attribution - Multi-Touch [#conversion-attribution---multi-touch] [Conversion Attribution](/docs/attribution/conversion-attribution) is full-journey multi-touch attribution (MTA). It splits conversion credit across every source, medium, and campaign that touched a visitor before they converted, using six attribution models (First Touch, Last Touch, Linear, U-Shaped, J-Shaped, and Time Decay) so you can see past last-click reporting. [How each model splits credit](/docs/attribution/conversion-attribution#how-each-model-splits-credit) works through the differences on one journey. Lookback windows of 7, 14, 30, or 60 days, with results broken down by source, medium, and campaign, and exportable to CSV. > **Early access.** Conversion Attribution is rolling out gradually. Contact your account representative to turn it on for your organization. ### UTM Performance Comparison [#utm-performance-comparison] [UTM Performance Comparison](/docs/attribution/utm-performance-comparison) builds a side-by-side table of specific UTM combinations and compares them on visitors, sessions, events, and conversion rate. Best for head-to-head campaign questions like "did the email campaign or the paid social campaign drive more bookings?" ### Audience Performance [#audience-performance] [Audience Performance](/docs/attribution/audience-performance) measures how an audience you define from session activity converted on a chosen event and the revenue it drove: conversion rates, revenue metrics, and a source/medium/campaign breakdown for any audience you define. ### Funnels [#funnels] [Funnels](/docs/attribution/funnels) measure conversion and drop-off across an ordered, multi-step path you build, with step-level filters, configurable conversion windows, and session replays of the visitors who fell out. Reach for it when the question is "where in my flow do people leave?" rather than "which channel gets credit?" ### Journey Explorer [#journey-explorer] [Journey Explorer](/docs/attribution/journey-explorer) walks the paths visitors actually take, one step at a time. Pin a start or end point, then drill column by column to see the next steps visitors took (or the steps before). Open-ended path discovery, rather than a fixed set of steps you define up front. > **Early access.** Journey Explorer is part of Journeys, which is rolling out gradually. Contact your account representative to turn it on for your organization. ### Conversion Journey Summary [#conversion-journey-summary] [Conversion Journey Summary](/docs/attribution/conversion-journey-summary) summarizes how visitors reach a conversion event: how many converted, how long it took, how many touchpoints they had, which sources started and closed the journey, and the page flow into the conversion. First-touch and last-touch source breakdowns within an attribution window you choose. > **Early access.** Conversion Journey Summary is part of Journeys, which is rolling out gradually. Contact your account representative to turn it on for your organization. *** ## What Attribution Is Built On [#what-attribution-is-built-on] Every view above is only as good as the journeys behind it, and journeys are only correct if the same person's activity is connected in the first place. * **[Visitor Identity and Matching](/docs/visitor-identity-and-matching)**: how one person's touchpoints are connected across devices, browsers, and sessions using server-set first-party cookies, the identifiers you send, and Identity Recovery. * **[Custom Domains](/docs/custom-domains)**: serve the SDK first-party so the visitor cookie is server-set and survives browser tracking prevention. The single highest-leverage step for attribution accuracy. * **[DSP View-Through Conversions](/docs/view-through-conversions)**: credit impressions that drove a conversion without a click, for programmatic, CTV, and audio campaigns. *** ## Need Help? [#need-help] Have a question about which tool fits, or how the numbers work? See the [Attribution FAQs](/docs/attribution/faqs), or reach out to [support@oursprivacy.com](mailto:support@oursprivacy.com). Journey Explorer walks the exact paths visitors take through your site, one step at a time. Pin a start or end point, then drill column by column to see where people went next, or what they did just before. Journey Explorer > **Early access.** Journey Explorer is part of Journeys, which is rolling out gradually. Contact your account representative to turn it on for your organization. Looking to measure drop-off across a fixed set of steps you define in advance? Use [Funnels](/docs/attribution/funnels). Journey Explorer is open-ended: instead of defining the steps up front, you pin one step and let the paths visitors actually took reveal the next step for you. *** ## What It Shows [#what-it-shows] Pick a step, and Journey Explorer shows you the most common next steps visitors took right after it within the same visit, ranked by how many took each one. Pin one of those steps and the next column shows what came after it, and so on. Walk far enough and you can trace a whole route through your site. You can walk forward from a **start point** ("once someone did this, where did they go next?") or backward from an **end point** ("what did people do right before this?"). Steps can be page views, tracked events, or both. *** ## Permissions [#permissions] Journey Explorer uses the **Web Analytics** permission set: | Permission | Capabilities | | ------------------------ | -------------------------------------------------------------------------------------------------- | | **Web Analytics: View** | Explore paths: change the date range and audience filters, walk every column, and read the results | | **Web Analytics: Write** | All View capabilities, plus saving a filter combination as a reusable segment | If you don't have the required permission, ask your account administrator to grant Web Analytics access. *** ## Building a Report [#building-a-report] Navigate to **Attribution Center > Journey Explorer**. ### Step 1: Choose a Date Range and Audience [#step-1-choose-a-date-range-and-audience] Set the **date range** for the paths you want to explore. Use the **Filter** button to scope the report to a subset of visitors with the same audience filters available across Web Analytics: UTM parameters, traffic source, location, device, browser, and more. You can also select a single web source and toggle whether bots are excluded. If you have Write access, save a filter combination as a segment to reuse it later. ### Step 2: Choose Which Steps to Include [#step-2-choose-which-steps-to-include] Use the step-kind toggle to decide what counts as a step: | Option | Includes | | ---------- | ---------------------------------- | | **All** | Both page views and tracked events | | **Pages** | Page views only | | **Events** | Tracked events only | Switching the step kind resets the walk. ### Step 3: Pick a Direction and a Starting Step [#step-3-pick-a-direction-and-a-starting-step] In the first column, choose a walk direction: * **Start point** walks forward: the columns to the right show what visitors did *after* the step you pin. * **End point** walks backward: the columns show what visitors did *before* it. Search the first column for the step you want, then click it to pin it. Pinning a step reveals the next column and scrolls it into view. ### Step 4: Walk the Path [#step-4-walk-the-path] Each new column ranks the most common next (or previous) steps for the visitors who reached the pinned step. Click a step to pin it and open the following column, or click an already-pinned step to collapse everything to its right. Use the per-column search to find a specific step, and **Show more** to load additional steps in a column. Click **Reset** at any time to clear the whole walk and start over. Journey Explorer showing a pinned starting step and successive visitor-path columns. *** ## Reading the Columns [#reading-the-columns] Each column represents one step in the path. * **Column heading.** The first column reads **Start point** or **End point**. Each column after it reads **1 step after**, **2 steps after**, and so on (or **1 step before**, **2 steps before** when walking backward). * **Step rows.** Each row shows the step, an icon for its type (page or event), the number of sessions that took that step, and its share of the column's sessions, with a proportional bar behind it. * **Percentages.** In the first column, the percentage is the share of all sessions that included the step, counted independently for each step, so a session that touched several different steps is reflected in each of their shares. In later columns, it is the share of the previous step's sessions whose next step this was. When a column mixes pages and events (the **All** step kind), page steps and event steps are ranked against the same sessions, so their shares can add up to more than 100%; a Pages-only or Events-only column stays at or below 100%. * **Conversion rate.** Once you pin a step, the column shows the share of the start step's sessions that reached it, so you can see how many visitors made it this far along the path. * **Ended here / Started here.** A terminal row captures the sessions that went no further (or, when walking backward, had no earlier step). An **Other** row rolls up the long tail of less-common steps. Neither can be pinned. * **Small sample.** When a column is built from fewer than 30 sessions, it carries a **small sample** badge, a reminder that the percentages there are noisy. *** ## When to Use This Tool [#when-to-use-this-tool] Reach for Journey Explorer when you want to discover the paths visitors actually take, rather than measure a route you defined in advance. When the steps are known in advance and you want conversion and drop-off across them, use [Funnels](/docs/attribution/funnels). When you want to summarize how converters reached a specific conversion event, use [Conversion Journey Summary](/docs/attribution/conversion-journey-summary). *** ## Next Steps [#next-steps] * **[Conversion Journey Summary](/docs/attribution/conversion-journey-summary)**: summarize the sources, timing, and page flow behind a conversion event. * **[Funnels](/docs/attribution/funnels)**: measure conversion and drop-off across steps you define. * **[Attribution FAQs](/docs/attribution/faqs)**: attribution models, date-range limits, exports, and more. UTM Performance Comparison lets you line up specific campaigns or UTM combinations side by side and compare how each one performed against a conversion event. UTM Performance Comparison Use this tool for head-to-head questions like "did the email campaign or the paid social campaign drive more bookings?" If you want credit spread across a visitor's whole journey instead of comparing fixed campaigns, use [Conversion Attribution](/docs/attribution/conversion-attribution). *** ## What It Shows [#what-it-shows] You define each comparison as a UTM combination (for example, `source: google` plus `medium: cpc`), give it an optional label, and the tool measures all of them against the same conversion event and date range. The result is one row per comparison, side by side, so differences in reach and conversion are easy to spot. *** ## Building a Comparison [#building-a-comparison] Navigate to **Attribution Center > UTM Performance Comparison**. ### Step 1: Choose the Conversion Event and Date Range [#step-1-choose-the-conversion-event-and-date-range] Select the event to measure from the dropdown, which lists every event your website is tracking. Then choose a date range of up to 31 days. The date range is capped at 31 days. Ranges longer than that aren't supported. ### Step 2: Choose an Attribution Model [#step-2-choose-an-attribution-model] Pick **First Touch** or **Last Touch** to decide which session in a visitor's path the comparison attributes to. ### Step 3: Add Comparison Rows [#step-3-add-comparison-rows] Add up to five comparison rows. For each row: 1. Give it an optional label (for example, "Holiday email" or "Brand search") to make the table easy to read. 2. Choose a combination of UTM filters from source, campaign, medium, content, term, and name. Each filter is optional, but a row needs at least one. Each field suggests the values already seen for your selected event and date range, and you can type a custom value if you don't see the one you want. You can edit or delete any row later, and editing a row's UTM filters recalculates that row against the current event and date range. *** ## Reading the Table [#reading-the-table] UTM Performance Comparison table comparing campaign combinations by visitors, sessions, events, and conversion rate. Each comparison appears as a row with these columns: | Column | Description | | ------------ | ----------------------------------------------------------------------------------- | | UTM Filters | The combination defining the row, shown as labeled badges, plus your optional label | | Visitors | Distinct visitors matching the combination | | Sessions | Sessions matching the combination | | Total Events | Occurrences of the chosen event for those visitors | | Conv Rate | Total events divided by visitors | | % of Total | This row's events as a share of events across all comparison rows | Every column is sortable, so you can rank comparisons by reach (Visitors) or by efficiency (Conv Rate). Click the Visitors count on any row to open those visitors in Web Analytics, filtered to the same event, date range, and UTM combination. Conv Rate is calculated as total events divided by visitors, so it can read above 100% when visitors trigger the event more than once. Read it as events per visitor rather than a funnel completion rate. It is also not the same metric as the Conversion Rate in [Audience Performance](/docs/attribution/audience-performance), which is unique converters divided by audience size, so the two are not directly comparable. Your event, date range, attribution model, and comparison rows are remembered in your browser, scoped to the organization you're viewing, so they're still there when you come back. Use the **Export** button in the page header to download the comparison table as a ZIP of CSV files. *** ## When to Use This Tool [#when-to-use-this-tool] Reach for UTM Performance Comparison when you already know the campaigns you care about and want them measured against each other. To explore an event without knowing the channels in advance, use [Event Attribution Insights](/docs/attribution/event-attribution-insights). To split credit across a full multi-touch journey, use [Conversion Attribution](/docs/attribution/conversion-attribution). *** ## Next Steps [#next-steps] * **[Event Attribution Insights](/docs/attribution/event-attribution-insights)**: explore one event and the visitors behind it. * **[Conversion Attribution](/docs/attribution/conversion-attribution)**: full-journey multi-touch credit across six models. * **[Attribution FAQs](/docs/attribution/faqs)**: conversion-rate math, date-range limits, exports, and more. Destinations An Audience Destination receives the **membership of an audience** rather than a stream of events. You build the audience once in the [Audience Builder](/docs/audiences/building-an-audience), pick which Audience Destinations it syncs to, and Ours Privacy sends the matching people to that platform daily so you can target them in your campaigns. Because these destinations receive people and not events, they have no allowed events and no event mappings. A single settings page holds the credentials, and the audience itself decides who gets sent. *** ## Why use an Audience Destination [#why-use-an-audience-destination] * **No manual CSV round trip.** The audience is rebuilt and re-sent daily, so your targeting keeps up with your data instead of aging from the moment you exported it. * **You control what identifiers are sent.** Your criteria decide who is included, and each destination's settings decide which identifiers it can receive. Enabled identifiers are hashed in the form the receiving platform specifies rather than sent as raw values. * **Membership behavior is destination-specific.** Vibe and Meta replace their full membership every run. Google refreshes a one-day membership window. MNTN adds or updates members it receives, so removals need to happen in MNTN. * **One audience, several platforms.** Attach the same audience to more than one Audience Destination and each gets its own independent sync. * **Nothing to schedule.** There is no job to configure or trigger. Selecting the destination on the audience is the whole setup. *** ## Available Audience Destinations [#available-audience-destinations] **[Vibe CTV Audiences](/docs/audiences/vibe-ctv-audiences)**, **[MNTN Audiences](/docs/audiences/mntn-audiences)**, **[Facebook Custom Audiences](/docs/audiences/facebook-custom-audiences)**, and **[Google Customer Match](/docs/audiences/google-customer-match)** sync today. If a destination is listed in the app but has no page here, check with your account representative before planning campaigns around it. *** ## How syncing works [#how-syncing-works] 1. Once a day, Ours Privacy re-evaluates every published audience that has at least one Audience Destination selected, so each run reflects who matches today rather than who matched when you created the audience. 2. Each audience and destination pair syncs on its own, so a platform that rejects one upload cannot hold up the others. 3. Each member's enabled identifiers are hashed in the form the platform specifies, duplicates are collapsed, and members with no usable identifier are skipped. 4. The destination updates the platform audience according to its membership model. Check the destination page for removal behavior. A run is skipped when the destination is **Disabled**, or when the destination has not been included in a published version yet. *** ## What the platform receives [#what-the-platform-receives] The audience's **Export Name** and the enabled, hashed identifiers. Your internal audience name and filter criteria stay in Ours Privacy. Each identifier is hashed with SHA-256 before upload in the form the receiving platform specifies. Platforms differ in which identifiers they accept and how they normalize them, so the specifics live on each destination's page. The Export Name is the one label that reaches the platform, and the platform displays it in its own interface, so keep it meaningless. A simplified form of the name is sent (lowercase and hyphenated). See [Export names](/docs/audiences/export-names) for how to set it. > **Important:** Advertising platforms are not HIPAA business associates and their terms typically prohibit uploading protected health information or consumer health data. Ours Privacy asks you to accept data-sharing terms before an audience can sync. See [Compliance for audiences](/docs/audiences/compliance). *** ## Match rates and minimums [#match-rates-and-minimums] A platform can only match a hashed identifier against a person it already recognizes, so expect the platform-side audience to be smaller than the count in Ours Privacy. **A low match rate is not an error anywhere.** The upload succeeds, the platform reports the audience as active, and it simply matches fewer people than you expected. Nothing fails, so nothing tells you. Two numbers are worth checking whenever a synced audience underperforms: * **How many members had an enabled usable identifier.** Ours Privacy records the delivered count against the audience total for every sync, which makes it obvious when most of an audience had nothing to match on. If the two numbers are far apart, the fix is in your data collection or your audience criteria, not on the platform side. * **The platform's own minimum before a list is usable for targeting.** Meta and Google each publish one, and a list below it can look healthy while never becoming targetable. The individual destination pages cover the current figures and where the platform reports your match rate. If the delivered count looks healthy but the platform reports few or no matches, contact [support@oursprivacy.com](mailto:support@oursprivacy.com) with the audience and the destination. *** ## Next Steps [#next-steps] * **[Syncing to destinations](/docs/audiences/syncing-to-destinations)** to set up a sync on an audience. * **[Vibe CTV Audiences](/docs/audiences/vibe-ctv-audiences)** and **[MNTN Audiences](/docs/audiences/mntn-audiences)** for destination setup. * **[Compliance for audiences](/docs/audiences/compliance)** for the terms, naming, and applying consent. * **[Destination Overview](/docs/destination-overview)** for how destinations work across the platform. Need help? Contact [support@oursprivacy.com](mailto:support@oursprivacy.com). Use this page to build an audience from start to finish. It assumes you know what you want to target; if you want the model first, read [Audience concepts](/docs/audiences/concepts). > **Important:** Advertising platforms are not HIPAA business associates and do not sign BAAs. Read [Compliance for audiences](/docs/audiences/compliance) before sending an audience to any platform. Audiences *** ## 1. Create the audience [#1-create-the-audience] 1. Open [Audiences](https://app.oursprivacy.com/marketing-center/audience-builder) in the dashboard. 2. Choose to add a new audience and give it a name. 3. Save. You land on the audience's detail page, where everything else happens. If the page asks you to request access instead, your account does not have audiences enabled yet, or you have reached your account's audience limit. Contact your account representative. *** ## 2. Set both names before anything else [#2-set-both-names-before-anything-else] Two name fields sit at the top of the page, and it is worth filling them in now rather than at the end. **Name** is for your team. Make it as specific as you like: it never leaves Ours Privacy, and a vague internal name is the main reason people later cannot tell two audiences apart. The field's own help text puts it plainly: it is what distinguishes this audience from other similar ones. **Export Name** is the label that appears in the file name of every CSV you download and in the advertising platform's own interface for every audience you sync. Press **Generate** to get a neutral one, or type your own. Do not describe the audience here. A generated name looks like `amber-harbor-drum`: three unrelated words. It carries no meaning, which is the point. If you type your own, keep it meaningless because the platform displays it verbatim. See [Export names](/docs/audiences/export-names) and [Compliance for audiences](/docs/audiences/compliance). *** ## 3. Add conditions [#3-add-conditions] An audience needs at least one condition. You can use either section on its own or both together. Audience Builder detail page with private and export names, an accepted-consent visitor condition, and event-condition controls. ### Visitor Properties [#visitor-properties] Filter on attributes of the visitor: consent categories, first-touch UTM parameters, city and country, and any custom properties you collect. 1. In the **Visitor Properties** card, add a condition. 2. Pick a property, then an operator, then a value if the operator needs one. 3. Add more conditions and set the connector between them to AND (narrower) or OR (broader). Audience Builder event-condition controls with an event, count rule, and rolling 30-day window. A good first condition for anything advertising-related is a consent condition. Nothing applies consent for you, so if it bears on who may be shared, add it here. See [Visitor conditions](/docs/audiences/visitor-conditions). ### Event Behavior [#event-behavior] Filter on what visitors did. Each condition reads as "performed this event this many times in the last this many days," optionally narrowed to the occurrences whose own properties match. 1. In the **Event Behavior** card, add an event condition. 2. Pick or type an event name, set the count operator and count, and set the day window. 3. Optionally add nested conditions so that only matching occurrences count, for example page views whose URL contains `/appointments`. The count operator is what makes exclusions possible. A condition of zero occurrences means the visitor never did that thing, which is how you target people who browsed but never converted. See [Event conditions](/docs/audiences/event-conditions). To target the visitors who saw a particular experiment variant, use **From experiment** in the Event Behavior card. It fills in the right condition for you. See [Experimentation](/docs/experimentation). *** ## 4. Preview and adjust [#4-preview-and-adjust] Save your changes, then press **Preview**. You get an estimated count and a sample table of matching visitors showing email, name, city, state, country, first seen, last seen, and consent. Read both. The count tells you whether the audience is the size you expected; the sample tells you whether the right people are in it. A count that is much larger than expected usually means an event condition has no nested filter and is counting every page view rather than the pages you care about. Preview needs your changes saved first, so the button waits until there is nothing unsaved. See [Previewing an audience](/docs/audiences/previewing-an-audience). *** ## 5. Activate it [#5-activate-it] Two ways out, and you can use both on the same audience. **Download a CSV.** Press **Export CSV** in the header and pick a format: all fields with raw values for internal use, or a layout formatted and hashed for Google Ads or Meta. The file lands in your browser, and a recent export stays listed on the audience so you can download the same file again. See [Exporting a CSV](/docs/audiences/exporting-csv). **Sync it to a platform.** In the **Sync to Destinations** card, accept the data-sharing terms, select the Audience Destinations you want, and save. Membership is then sent daily. Each destination handles adds and removals in its own way. See [Syncing to destinations](/docs/audiences/syncing-to-destinations). **Export CSV** is enabled only when the audience has a name, has at least one condition, and has no unsaved changes. If it looks disabled, one of those three is the reason. *** ## Managing audiences over time [#managing-audiences-over-time] **Duplicate** an audience from the audience list when you want a variant. Copying a working definition and changing one condition is faster and safer than rebuilding it, and it is the normal way to produce the "already converted" counterpart to an inclusion audience. Give the copy its own Export Name. **Publish** the audience when you want it to run on its own. Publishing requires at least one condition. Unpublishing stops a published audience from being used by automated processes. **Delete** removes the audience. Anything you already downloaded stays on your machine, and a synced audience should be stopped from the **Sync to Destinations** card first so it stops being sent before the definition disappears. Each of create, edit, preview, export, publish, and delete is governed by its own permission. If an action is disabled and the audience looks otherwise fine, ask your account administrator for the matching access. *** ## Next Steps [#next-steps] * **[Visitor conditions](/docs/audiences/visitor-conditions)** for every property and operator. * **[Event conditions](/docs/audiences/event-conditions)** for counts, windows, and event property filters. * **[Recipes](/docs/audiences/recipes)** for worked configurations you can copy. * **[Syncing to destinations](/docs/audiences/syncing-to-destinations)** to set up the daily send. Need help? Contact [support@oursprivacy.com](mailto:support@oursprivacy.com). Use this page before you send an audience to an advertising platform. It covers what Ours Privacy does on your behalf, what it deliberately does not do, and what remains your decision. This page describes product behavior and the terms you accept in the product. It is not legal advice, and your own counsel is the right party to tell you whether a particular audience may be shared. *** ## The four things to know [#the-four-things-to-know] These are the points you confirm in the product before an audience can sync, restated here so you can read them without a dialog in the way. **Advertising platforms are not HIPAA business associates.** Vibe, Meta, and Google do not sign business associate agreements, and their terms prohibit uploading protected health information or consumer health data. A platform that will not sign a BAA is, under HHS guidance on tracking technologies, a party that may only receive de-identified data. **The audience's Export Name travels with it.** That is the only name the platform sees; your internal name never leaves Ours Privacy. Meta prohibits audience names that reflect or imply health information, and the Export Name is displayed verbatim in the platform's interface, so it must not describe a condition, treatment, or medication. Choosing a name that satisfies that is yours to do. See [Naming an audience you are about to share](#naming-an-audience-you-are-about-to-share) below. **You are responsible for having a lawful basis.** That includes any consent your visitors must give before you share them with a platform. Building an audience does not automatically consider a visitor's consent status: an audience of "viewed a page in the last 30 days" matches everyone who did, whatever they told your banner, and a sync sends exactly the audience you defined. If consent matters for this audience, require it in the audience itself. *** ## The data-sharing acknowledgement [#the-data-sharing-acknowledgement] Before an audience can sync anywhere, someone on your account accepts data-sharing terms covering the four points above, and confirms that they have the authority and a lawful basis to share the audience with the selected platforms and that the audience does not contain protected health information or consumer health data. The acceptance is recorded on the audience with who accepted it, when, and which version of the terms they saw. The **Sync to Destinations** card shows the date it was accepted. Two behaviors worth knowing. The version is stored rather than a plain yes, so an acceptance of one version of the terms is never later presented as acceptance of a different one. And removing the last destination from an audience clears the acknowledgement, so re-enabling a sync later means reading and accepting the terms again rather than inheriting a decision somebody made months ago. *** ## Consent [#consent] Ours Privacy does not filter an audience on consent. A sync sends the audience as you defined it, and so does a CSV. If consent should bear on who is shared, add it to the audience as a condition. Two conditions cover the common cases, both on the **Visitor Properties** card: * **Opt-out posture:** Rejected Consent Categories **does not contain** `advertising`. Excludes recorded rejections. A visitor with no consent record is not a rejection and still matches. * **Opt-in posture:** Accepted Consent Categories **contains** `advertising`. Matches only visitors who actively accepted, which is a much smaller audience if most of your traffic predates your banner. Because the condition lives in the audience, the preview counts it: what you see before you sync is what the sync sends. See [Visitor conditions](/docs/audiences/visitor-conditions). *** ## Naming an audience you are about to share [#naming-an-audience-you-are-about-to-share] The Export Name is rendered verbatim in the advertising platform's own interface. That makes the name a piece of information the platform receives, separate from the member list. Consider an audience called `diabetes-followup-q3`. Every identifier in it is hashed, and no condition or criteria are sent. The platform still learns that the people in that list were grouped by a diabetes-related concern, because the name says so and the membership says who. Hashing protects the identifiers; the name is not an identifier. The platforms require this of you directly. Meta's Business Tools Terms state that the names you choose and criteria you establish for custom audiences must not reflect, imply, or be based on health information. Google's Customer Match policy prohibits lists that contain or imply sensitive information including health conditions. The FTC has charged companies over exactly this: the GoodRx complaint identified custom audiences named after specific medications and conditions. Choosing the name is yours. Put the description in **Name**, which never leaves Ours Privacy, and press **Generate** for the Export Name. An audience named `Post-Discharge Follow-Up, No Appointment Booked` internally with an Export Name of `copper-lantern-cove` gives you both: your team knows what the audience is, and the platform learns nothing. Rewording a descriptive name is not the fix. It usually produces a slightly less obvious descriptive name, which is the same disclosure with extra steps. Move the meaning to the internal field instead. See [Export names](/docs/audiences/export-names). *** ## What actually leaves Ours Privacy [#what-actually-leaves-ours-privacy] For a **sync**, the audience's Export Name and the enabled hashed identifiers for each member. The receiving destination determines which identifiers it supports. MNTN can receive hashed email addresses and phone numbers when you enable them in its destination settings. Nothing else goes: not names, not addresses, not your conditions, not your internal audience name, not counts. For a **CSV export**, what you chose. The all-fields format contains raw visitor values and is for internal use. The Google and Meta formats contain up to six and ten columns respectively, hashed to each platform's specification. You control where that file goes, which makes a downloaded CSV the higher-risk artifact of the two. See [Exporting a CSV](/docs/audiences/exporting-csv). Your **internal name**, your **conditions**, and every visitor attribute outside the chosen export never leave. *** ## Evidence for a compliance review [#evidence-for-a-compliance-review] If you are the person who has to show an auditor what happened, three things are worth knowing about where the record lives. **The acknowledgement is the receipt for the decision.** Who accepted the data-sharing terms, when, and which version they saw is recorded on the audience itself and shown in the **Sync to Destinations** card. That is the artifact that answers "who authorized sharing this audience." **The audience definition is the record of who was included.** Because an audience is a set of conditions rather than a saved list, the conditions are the documentation of the population. Keeping the internal **Name** descriptive is what makes that legible six months later. **Wider organizational activity has its own tools.** For periodic access and configuration review across your account, see [Audit Log](/docs/audit-log). For what is being forwarded to which third parties across the platform, see [Compliance Report](/docs/compliance-report) and [Consent Analytics](/docs/consent-analytics). *** ## Audience size and re-identification [#audience-size-and-re-identification] Platform minimums exist partly for privacy reasons: a very small audience makes the people in it easier to single out. Meta's guidance for a customer list is at least 1,000 people, and Google recommends at least 5,000 members for a Customer Match list to have a reasonable chance of serving. A tiny audience is worth a second look for a reason beyond targeting effectiveness. An audience of eleven people sent to a platform under any name is a much more specific statement about those eleven people than a list of fifty thousand. *** ## Practices worth adopting [#practices-worth-adopting] **Name the audience for your team, not for the platform.** Descriptive internal name, meaningless Export Name, every time. See [Export names](/docs/audiences/export-names). **Put consent in the audience.** Nothing applies it for you. If consent bears on whether someone may be shared, it belongs in the conditions, where you can see it and the preview counts it. **Decide who may accept the terms.** The acknowledgement is a statement about your organization's authority and lawful basis. Accepting the terms and selecting destinations are governed by permissions, so the people who can do it should be the people who can make that statement. Ask your account administrator about access. **Review synced audiences on a schedule.** A daily sync keeps running until somebody stops it. An audience built for a campaign that ended six months ago is still being sent. **Treat downloaded CSVs as the loose end.** A file on somebody's laptop has left every control the platform gives you. A recent export can be downloaded again from the audience, so re-downloading when you need it is usually better than keeping a copy. *** ## Next Steps [#next-steps] * **[Export names](/docs/audiences/export-names)** for setting and changing the destination-facing name. * **[Syncing to destinations](/docs/audiences/syncing-to-destinations)** for the sync setup and what each run sends. * **[Audience Destinations](/docs/audiences/audience-destinations)** for per-platform behavior and minimums. * **[Cookie Consent](/docs/cookie-consent)** for collecting the consent an audience can then require. Need help? Contact [support@oursprivacy.com](mailto:support@oursprivacy.com). Use this page to understand what an audience actually is in Ours Privacy before you build one. Everything here explains the model; the walkthrough lives in [Building an audience](/docs/audiences/building-an-audience). > **Important:** Advertising platforms are not HIPAA business associates and do not sign BAAs. Read [Compliance for audiences](/docs/audiences/compliance) before sending an audience to any platform. *** ## An audience is a definition, not a list [#an-audience-is-a-definition-not-a-list] An audience is a set of conditions, not a saved list of people. Nothing is frozen at the moment you create it. Every time the audience is used, whether for a preview, a CSV export, or a daily sync, the conditions run again against your current data and produce the membership as of that moment. That is why an audience you built in March can be synced in July and reflect July's visitors. It is also why the same audience can return a different count two days in a row without anything having changed in the definition. **Why it matters:** you never maintain a list. You maintain a description of the people you want, and membership follows your data. The flip side is that an audience is only as good as the criteria you wrote, and a condition that is subtly too broad stays subtly too broad on every run until you fix it. *** ## Two kinds of conditions [#two-kinds-of-conditions] Conditions come from two places, and the distinction matters because they answer different questions. **Visitor properties** describe who someone is: the consent categories they accepted or rejected, the UTM parameters on their first visit, their city or country, and any custom properties you send. These are attributes on the visitor record. See [Visitor conditions](/docs/audiences/visitor-conditions). **Event behavior** describes what someone did: how many times they fired a given event inside a rolling window, optionally narrowed to the events whose own properties match a filter. See [Event conditions](/docs/audiences/event-conditions). You can use either alone or both together, and both sections support AND and OR between their conditions. When you use both sections, a visitor has to satisfy both. The most precise audiences are usually a visitor property baseline (consent, attribution) plus an event pattern (funnel stage, engagement). An audience with no conditions at all is not usable. Preview, export, and publish all require at least one condition, because an audience with no conditions means everybody. *** ## Every audience carries two names [#every-audience-carries-two-names] This is the part that is unusual, and it exists for a specific reason. The **Name** is yours. It is as descriptive as you want, it stays inside Ours Privacy, and nobody outside your account ever sees it. "Visited the addiction recovery page twice, never booked a consult" is a good internal name. The **Export Name** is the only string that leaves. It appears in the file name of every CSV you download and it is the label an advertising platform displays in its own interface. That name is a disclosure on its own: the platform learns what the audience is about, independently of who is in it and independently of whether identifiers were hashed. So Ours Privacy keeps them separate rather than deriving one from the other. Deriving is the whole problem, because any transformation of `addiction-recovery-visitors` still says addiction. See [Export names](/docs/audiences/export-names) for how to set one, and [Compliance for audiences](/docs/audiences/compliance) for what the platforms require of it. *** ## Published means ready to run on its own [#published-means-ready-to-run-on-its-own] Saving an audience keeps your edits. Publishing marks the definition as the one that automated processes should use. An audience needs at least one condition before it can be published, and a published audience can be unpublished if you want it to stop running. Downloading a CSV does not require publishing, because you are asking for a result right now. A daily sync does, because nobody is present to confirm that the current draft is what you meant. *** ## Exporting and syncing are different acts [#exporting-and-syncing-are-different-acts] Both start from the same audience definition, but they behave differently enough that it is worth being explicit. | | Export a CSV | Sync to a destination | | -------------------- | ------------------------------------------ | ------------------------------------ | | Who triggers it | You, each time | Runs daily on its own | | What you get | A file you download and upload yourself | Membership delivered to the platform | | Formats | All fields raw, or a Google or Meta layout | The platform's own required form | | Identifiers included | Depends on the format, up to ten columns | The enabled hashed identifiers | | Removals | You manage them in the platform | Depends on the destination | Both send the audience as you defined it. Neither filters on consent, so if consent bears on who may be shared, add it to the audience as a condition. See [Exporting a CSV](/docs/audiences/exporting-csv), [Syncing to destinations](/docs/audiences/syncing-to-destinations), and [Compliance for audiences](/docs/audiences/compliance). *** ## Audience Destinations are not event destinations [#audience-destinations-are-not-event-destinations] Most destinations in Ours Privacy receive events: a visitor did something, and that fact is forwarded with your mappings applied. An Audience Destination receives membership instead: here are the people currently in this audience. That difference shows up in the setup. An Audience Destination has no allowed events and no event mappings, only credentials, and the audience itself decides who gets sent. It also means you cannot sync an audience to an ordinary event destination, and selecting an event destination is not offered. Some platforms appear twice for exactly this reason. MNTN has an events destination that measures what your campaigns drove and a separate MNTN Audiences destination that gives MNTN people to target. Running both is normal. See [Audience Destinations](/docs/audiences/audience-destinations). *** ## A destination decides which identifiers it matches on [#a-destination-decides-which-identifiers-it-matches-on] A CSV export can include up to ten identifier columns depending on the format you pick. A sync sends the enabled hashed identifiers supported by that destination. Vibe uses hashed email. MNTN can use hashed email, hashed phone, or both. The practical consequence is that a visitor with none of a destination's enabled identifiers cannot be part of that sync, no matter how well they match your conditions. They are skipped, and Ours Privacy records how many members were delivered against how many were in the audience so the gap is visible rather than silent. If most of your audience lacks an enabled identifier, the fix is in how you capture that identifier, or in adding a condition that requires one. It is not something the platform can solve. *** ## A low match rate is not an error [#a-low-match-rate-is-not-an-error] Platforms match the hashed identifiers they receive only against people they already recognize. The audience on the platform side will be smaller than your count, sometimes much smaller, and nothing about that produces a failure. The upload succeeds, the platform reports the audience as active, and it simply matches fewer people than you expected. This is the one failure mode neither system reports, so it is worth knowing the two numbers to check: how many members Ours Privacy delivered against the audience total, and whatever match figure the platform reports on its side. See [Audience Destinations](/docs/audiences/audience-destinations). *** ## Next Steps [#next-steps] * **[Building an audience](/docs/audiences/building-an-audience)** for the end-to-end walkthrough. * **[Visitor conditions](/docs/audiences/visitor-conditions)** and **[Event conditions](/docs/audiences/event-conditions)** for the condition inventory. * **[Export names](/docs/audiences/export-names)** for the naming model in practice. * **[Compliance for audiences](/docs/audiences/compliance)** for what you are responsible for before syncing. Need help? Contact [support@oursprivacy.com](mailto:support@oursprivacy.com). Use this page as the reference for the **Event Behavior** section of an audience. Event conditions describe what visitors did rather than who they are; for attributes, see [Visitor conditions](/docs/audiences/visitor-conditions). > **Important:** Advertising platforms are not HIPAA business associates and do not sign BAAs. Read [Compliance for audiences](/docs/audiences/compliance) before sending an audience to any platform. *** ## What an event condition says [#what-an-event-condition-says] Every event condition answers one question: **did this visitor perform this event this many times in the last this many days?** Three parts make that up. 1. **The event.** Pick one from your account's events or type a name. The dropdown is built from the events your account actually collects. 2. **The count.** An operator and a number, for example at least 2, or exactly 0. 3. **The window.** A number of days, counted backwards from now on a rolling basis. A 30-day window today covers a different 30 days than it did last week. Optionally, a fourth part: **nested conditions** that narrow which occurrences of the event count at all. Audience Builder event-condition controls with an event, count rule, and rolling 30-day window. *** ## Count operators [#count-operators] | Operator | Reads as | | --------------------------- | ------------------------------------------------ | | is exactly | Performed it precisely this many times | | is not | Performed it any number of times other than this | | is greater than | More than this many times | | is greater than or equal to | At least this many times | | is less than | Fewer than this many times | | is less than or equal to | At most this many times | **At least** is the workhorse for inclusion. **At most zero** is the workhorse for exclusion, and it is worth its own section below. *** ## Time windows [#time-windows] The window is a rolling number of days. Some rough guidance on picking one. | Window | Fits | | ------------- | --------------------------------------------------------------------------------------- | | 3 days | Retargeting while your brand is still top of mind | | 7 days | Weekly engagement patterns | | 14 days | A campaign flight with a two-week cadence | | 28 to 30 days | The default for most audiences, and comparable to monthly reporting | | 90 days | Long consideration cycles, and audiences that would otherwise be too small to be usable | Two things to keep in mind. A longer window makes an audience larger but less current, which for retargeting is usually the wrong trade. And when several conditions in one audience use different windows, the audience means something more complicated than it reads like. If two conditions describe the same funnel, give them the same window unless you have a specific reason not to. *** ## Filtering which occurrences count [#filtering-which-occurrences-count] A bare event condition counts every occurrence of the event. That is almost never what you want for page views, because every page on your site fires one. Nested conditions fix that. They filter the individual occurrences, so only the ones matching count toward the total. Take "performed a page view at least twice in the last 30 days." On most sites that matches nearly every returning visitor. Add a nested condition that the page URL contains `/appointments` and it means something: two visits to the appointments section specifically. The properties available to nest on are the ones carried by the event itself: the page URL where it happened, the UTM values in effect at the time, and any properties you attach when you send the event. They are shown with the same labels you see elsewhere in the dashboard, and every operator from [Visitor conditions](/docs/audiences/visitor-conditions) works here too. **Rule of thumb:** if the event is a page view or another event that fires on many pages, it needs a nested URL condition. If the event is specific by nature, such as a form submission or a booking confirmation, it usually does not. *** ## The zero-count pattern [#the-zero-count-pattern] Setting the count to at most zero means the visitor never performed the event inside the window. This is how you exclude people, and it is the single most useful thing in this section. Almost every effective retargeting audience is built from a pair of conditions: * At least one occurrence of an interest signal, such as a view of a service page. * At most zero occurrences of the conversion, such as a view of the confirmation page. That combination targets exactly the people who showed interest and did not convert, which is where retargeting spend does the most good. Without the second condition you pay to advertise to people who already booked. The event you pick as the conversion matters. Use the last step that only completers reach: a confirmation or thank-you page rather than the first step of the form, which people abandon. See [Targeting strategies](/docs/audiences/targeting-strategies) for how this composes with exclusion audiences and lookalike seeds. *** ## Combining event conditions [#combining-event-conditions] **AND** requires the visitor to match every event condition. This is the normal choice, and it is what funnel-shaped audiences are made of: did this, did not do that. **OR** requires any one of them to match. Use it when several different events all count as the same signal, for example any of three different form submissions on your site. Event conditions also combine with the Visitor Properties section, and a visitor has to satisfy both sections. The precise audiences are almost always both: visitor properties set the baseline (consent, attribution), event conditions identify the behavior pattern. *** ## Building an audience from an experiment [#building-an-audience-from-an-experiment] To target the visitors who saw a specific experiment variant, use **From experiment** in the Event Behavior card. It fills in the impression event and the variant filter for you, which is faster and less error-prone than assembling it by hand. Two uses come up. Advertising to everyone who saw one variant, and suppressing them from a campaign so a different variant's audience stays clean. See [Experimentation](/docs/experimentation). *** ## Practical notes [#practical-notes] **Preview after every condition, not at the end.** An event condition that is subtly too broad looks identical in the interface to one that is right. The count is the only thing that tells you. **Watch for the audience that collapses to nothing.** Three AND conditions with mismatched windows can describe a sequence nobody actually performs. If Preview returns an unexpectedly tiny count, remove conditions one at a time to find which one is doing it. **Recent events are available quickly.** Event data becomes queryable within about fifteen minutes of collection, so an audience built on behavior from this morning works this afternoon. **Deliverability is separate from matching.** A visitor can match every event condition perfectly and still be skipped by a sync because their record has no enabled identifier. See [Audience Destinations](/docs/audiences/audience-destinations). *** ## Next Steps [#next-steps] * **[Visitor conditions](/docs/audiences/visitor-conditions)** for the attribute side and the full operator list. * **[Previewing an audience](/docs/audiences/previewing-an-audience)** to validate what you built. * **[Recipes](/docs/audiences/recipes)** for worked event configurations, including funnel exclusions. * **[Targeting strategies](/docs/audiences/targeting-strategies)** for exclusions, retargeting, and lookalike seeds. Need help? Contact [support@oursprivacy.com](mailto:support@oursprivacy.com). Use this page to understand the Export Name field and how to set one. Every audience has two names, and this is the second one: the only label that leaves Ours Privacy. > **Important:** Advertising platforms are not HIPAA business associates and do not sign BAAs. Read [Compliance for audiences](/docs/audiences/compliance) before sending an audience to any platform. *** ## Why an audience has two names [#why-an-audience-has-two-names] The obvious design is one name field. That design leaks. An audience name reaches places you do not control. It is rendered in the file name of every CSV you download, and for a synced audience it is displayed verbatim in the advertising platform's own interface, where the platform's staff can read it. So a name like `visited-addiction-recovery-no-consult-booked`, which is a perfectly good internal description, discloses a health condition to that platform on its own. It does so independently of who is in the list and independently of the fact that every identifier was hashed. The label plus the existence of the list is the disclosure. The fix is two fields rather than a restriction on one. **Name** stays inside Ours Privacy. Make it as descriptive as your team needs. Nobody outside your account sees it. **Export Name** is the only string that leaves. It should mean nothing. Deriving the second from the first would defeat the point, which is why Ours Privacy does not do it. Any transformation of `addiction-recovery-visitors` still says addiction. *** ## Setting one [#setting-one] The **Export Name** field sits directly under **Name** on the audience page. You have two options. **Press Generate.** You get a neutral three-word name, such as `amber-harbor-drum`. It carries no information about the audience, which is exactly what you want, and the words are chosen to be unambiguous when spoken aloud, so you can read one to an agency over the phone when they need to find the audience in a platform's interface. **Type your own.** Anything meaningless works. Project codes, internal reference numbers, and arbitrary word pairs are all fine. What is not fine is describing the audience. A name that describes a condition, treatment, medication, or clinical event discloses that to the platform on its own, and the platforms' own terms prohibit it. See [Compliance for audiences](/docs/audiences/compliance). *** ## What makes a good Export Name [#what-makes-a-good-export-name] Safe, in the sense that it says nothing about the people in the list: * `amber-harbor-drum`, `copper-lantern-cove`, `bright-compass-trail` (generated) * `Q3-A`, `campaign-4471`, `list-north` * `blue-harbor`, `north-star`, `silver-maple` Not safe, because each one describes a condition, treatment, or clinical intent: * `diabetes-patients-q3` * `booked-colonoscopy` * `cancer-reminder-list` * `oncology-followup-2026` * `mental-health-retarget` The test is simple. If someone at the advertising platform read only the name and could infer something about the health of the people in the list, it is the wrong name. *** ## The competitive angle [#the-competitive-angle] Health context is the sharpest reason to keep the name meaningless, but not the only one. The Export Name is visible to everyone with access to the ad account, and ad accounts are frequently shared with agencies, contractors, and platform support staff. An audience named `paid-search-nonconverters-providers-page` tells anyone looking exactly how you segment your funnel. A name like `amber-harbor-drum` tells them nothing. The field's own help text in the dashboard puts it this way: use a random name to prevent competitors from seeing your targeting strategy. Your internal name keeps all the meaning. You lose nothing by making the external one opaque. *** ## Where the Export Name shows up [#where-the-export-name-shows-up] **In every CSV file name.** A downloaded export is named after the Export Name plus the date it was generated. This applies to all three export formats, including the all-fields format you only use internally, because a file that starts out internal does not always stay that way once it is on somebody's desktop or in an email thread. **In the advertising platform's interface.** A synced audience appears in the platform under its Export Name. This is the name you search for when attaching the audience to a campaign, so keep it somewhere you can find it. The **Sync to Destinations** card shows you the exact form the platform will see and lets you copy it. **Nowhere else.** Your internal name, your conditions, your estimated counts, and every visitor attribute other than the hashed identifiers enabled for the destination stay in Ours Privacy. *** ## Renaming [#renaming] You can change the Export Name whenever you like, and the field is editable for the life of the audience. Two consequences to be aware of before you do. **Future CSV downloads use the new name.** Files you already downloaded keep the name they were generated with, so a rename does not make old files consistent with new ones. **A synced audience may appear under the new name on the platform.** If you have campaigns attached to that audience in a platform's interface, changing the name changes what you are looking for the next time you go in. Rename before you attach an audience to campaigns rather than after, where you have the choice. If you inherit an audience whose Export Name describes what it targets, renaming it is the right move, and it is worth doing even for an audience you only ever download as a CSV. *** ## When you have not set one [#when-you-have-not-set-one] Set the Export Name before you export or sync anything. It is a required part of the sync setup, and for a CSV it is what the file gets named. Pressing **Generate** takes a second and removes the decision entirely, which for most audiences is the right answer. *** ## Next Steps [#next-steps] * **[Compliance for audiences](/docs/audiences/compliance)** for why the name matters and what the platforms require. * **[Compliance for audiences](/docs/audiences/compliance)** for the wider obligations around sharing an audience. * **[Syncing to destinations](/docs/audiences/syncing-to-destinations)** for where the platform-facing name is shown. * **[Exporting a CSV](/docs/audiences/exporting-csv)** for how the file name is built. Need help? Contact [support@oursprivacy.com](mailto:support@oursprivacy.com). Use this page to download an audience as a file. If you want the audience delivered to a platform automatically instead, see [Syncing to destinations](/docs/audiences/syncing-to-destinations). > **Important:** Advertising platforms are not HIPAA business associates and do not sign BAAs. A downloaded CSV also leaves every control Ours Privacy has, so treat the file accordingly. Read [Compliance for audiences](/docs/audiences/compliance). *** ## Running an export [#running-an-export] 1. Save your changes. The **Export CSV** button is enabled only when the audience has a name, has at least one condition, and has nothing unsaved. 2. Press **Export CSV** in the header. 3. Choose a format. 4. Press **Export**. The export runs in the background, which for a large audience takes a few minutes, then the file downloads. The dialog stays useful if you close it. The export keeps running and you can reopen the audience later to collect the result from **Recent Exports**. Export CSV dialog offering All Fields, Google Ads, and Facebook Ads formats with hashed-data guidance. *** ## The three formats [#the-three-formats] ### All Fields [#all-fields] Every visitor column, raw values, nothing hashed. This is the internal format: CRM uploads, warehouse loads, analysis in a spreadsheet. It is the widest of the three by a long way, covering identity fields, location, first-touch and current-session UTM values, referrer and referring domain, ad platform click IDs, timestamps, and your custom properties. It is also the only format containing raw email addresses, so it is the one to be most careful with. ### Google Ads Format [#google-ads-format] Six columns, formatted for a Google Customer Match list: Email, Phone, First Name, Last Name, Country, and Zip. Email, phone, and the name fields are normalized and SHA-256 hashed to Google's specification. Country and Zip are sent as plain values, because that is what Google expects. Email normalization follows Google's rules, which for Gmail and Googlemail addresses means dots and any plus-suffix are removed before hashing. ### Facebook Ads Format [#facebook-ads-format] Ten columns, formatted for a Meta customer list: EMAIL, PHONE, FN, LN, CT, ST, ZIP, COUNTRY, DOB, and GEN. Every column is normalized and SHA-256 hashed to Meta's specification, which is stricter than Google's about punctuation: names and city are reduced to letters only, state to a two-character code, dates of birth to an eight-digit form, and gender to a single character. *** ## What the row counts mean [#what-the-row-counts-mean] Both ad platform formats report two numbers when the export completes, and the difference between them is the most useful thing on the screen. **Rows** is how many visitors matched your audience. **Rows with matchable data** is how many of them had at least one identifier, meaning an email address or a phone number, that a platform could match on. A visitor with a city and a first name but no email or phone cannot be matched by anyone, so they are filtered out of the file rather than shipped as an unmatched row. A result reading `4,102 of 38,540 rows had matchable data` is not an error. It is telling you that most of that audience has no identifier, and that the fix is in your data collection or in the audience conditions rather than at the platform. Adding a visitor condition requiring email to be not null makes this visible in Preview instead. See [Previewing an audience](/docs/audiences/previewing-an-audience). If none of the rows had matchable data, the export says so and offers the file anyway. Uploading it will not accomplish anything, but you may want it for diagnosis. The All Fields format reports a single row count, because it is not built for matching. *** ## The file name [#the-file-name] Every export is named after the audience's **Export Name** plus the date and time it was generated. This applies to all three formats. That is a deliberate consequence of the naming model: the internal name you use to describe the audience never reaches a file name, so a CSV that gets forwarded, saved to a shared drive, or attached to a ticket does not carry a description of who is in it. See [Export names](/docs/audiences/export-names). *** ## Recent exports [#recent-exports] Completed exports are listed on the audience under **Recent Exports**, with the export name, the format, when it ran, and the row counts. A finished export stays available to re-download for a limited window, after which it drops off the list and you run the export again. See [Data Retention](/docs/data-retention) for how retention works across the platform. Each download link is issued fresh when you press **Download**, and an individual link is short-lived. If a link stops working, go back to the audience and press Download again rather than reusing an old URL. Failed exports appear in the same list with the reason, which is usually more useful than retrying blind. *** ## Bulk exporting [#bulk-exporting] You can export several audiences at once from the audience list by selecting them and choosing to export. Each audience produces its own file in the format you pick, and each is named after its own Export Name. *** ## Practical notes [#practical-notes] **Consent is not filtered on a CSV.** A download contains everyone who matched, including visitors who rejected the advertising consent category. If you are exporting in order to upload to an ad platform by hand, add the consent condition to the audience yourself. See [Compliance for audiences](/docs/audiences/compliance). **Prefer syncing when a platform supports it.** A CSV is a snapshot from the moment you pressed the button, while a sync re-evaluates the audience daily. Review each destination's membership behavior before relying on automatic removals. See [Audience Destinations](/docs/audiences/audience-destinations). **Re-download rather than keep a copy.** A recent export can be downloaded again from the audience, and a copy on a laptop is outside every control the product has. **A large export takes minutes, not seconds.** It runs in the background, so you can close the dialog and come back. *** ## Next Steps [#next-steps] * **[Syncing to destinations](/docs/audiences/syncing-to-destinations)** to have the audience delivered daily instead. * **[Previewing an audience](/docs/audiences/previewing-an-audience)** to check the deliverable size before exporting. * **[Export names](/docs/audiences/export-names)** for the name the file gets. * **[Compliance for audiences](/docs/audiences/compliance)** for what to consider before a file leaves. Need help? Contact [support@oursprivacy.com](mailto:support@oursprivacy.com). Facebook Custom Audiences sends the members of an Ours Privacy audience to a Meta ad account. Ours Privacy creates one Custom Audience for each attached audience and replaces its membership during the daily sync. *** ## Before you start [#before-you-start] * A Meta ad account where the connected user can manage Custom Audiences. * Meta Custom Audience terms accepted for the business that owns the ad account. * Your own Meta app with the Marketing API permission required to manage audiences. * The Ours Privacy production redirect URI, `https://app.oursprivacy.com/integrations`, added to your Meta app's valid OAuth redirect URIs. *** ## Set up the destination [#set-up-the-destination] 1. In **Destinations**, add **Facebook Custom Audiences**. 2. Enter your Meta App ID and Meta App Secret. Ours Privacy does not use an Ours-owned OAuth app for this destination. 3. Select **Connect Meta Ads** and complete the Meta sign-in flow. 4. Enter the Meta Ad Account ID that will own the Custom Audiences. Enter digits only. 5. Choose the identifier groups you authorize Ours Privacy to send. Every group starts off. 6. Save and publish the destination. Ours Privacy stores the app secret as a secret setting and does not display it again after save. Reconnect the destination if Meta revokes the connection or its permissions change. *** ## Identifier choices [#identifier-choices] You choose whether to send each of these groups: * Email * Phone * Name and location: first name, last name, city, state, postal code, and country * Date of birth * Gender Each enabled value is normalized for Meta and hashed with SHA-256 before upload. Members with no usable enabled identifier are skipped. Meta never receives your audience conditions or internal audience name. *** ## Sync behavior [#sync-behavior] Ours Privacy evaluates attached audiences daily and replaces the prior Meta membership, so people who no longer match are removed on the next successful run. The Custom Audience is labeled with the audience's Export Name. Meta can take time to process uploads, and its matched audience count can be lower than the delivered count in Ours Privacy. Check Meta Ads Manager for the platform-side match and delivery status. Keep the Export Name neutral. It is visible in Meta Ads Manager and must not describe health information, financial status, or another sensitive characteristic. *** ## Next Steps [#next-steps] * **[Audience Destinations](/docs/audiences/audience-destinations)** for how audience syncing works. * **[Syncing to destinations](/docs/audiences/syncing-to-destinations)** to attach this destination to an audience. * **[Audience Builder](/docs/audiences/building-an-audience)** to build and export audiences now. Need help? Contact [support@oursprivacy.com](mailto:support@oursprivacy.com). Common questions about building, naming, exporting, and syncing audiences. For the underlying model, see [Audience concepts](/docs/audiences/concepts). > **Important:** Advertising platforms are not HIPAA business associates and do not sign BAAs. Read [Compliance for audiences](/docs/audiences/compliance) before sending an audience to any platform. *** ## Compliance and privacy [#compliance-and-privacy] ### Can I send a health-related audience to Meta or Google? [#can-i-send-a-health-related-audience-to-meta-or-google] > Not as protected health information or consumer health data. Advertising platforms do not sign business associate agreements and their own terms prohibit uploading that data. Whether a given audience crosses that line is a question for your counsel, not for the product. Ours Privacy enforces the parts it can enforce, which are the destination-facing name and the advertising consent exclusion, and the terms you accept before syncing set out the rest. See [Compliance for audiences](/docs/audiences/compliance). ### What should I call an audience I am about to sync? [#what-should-i-call-an-audience-i-am-about-to-sync] > Something meaningless. The Export Name is displayed verbatim in the advertising platform's interface, so a name that describes a condition, treatment, medication, or clinical event discloses that on its own, and the platforms' own terms prohibit it. Put the description in **Name**, which stays internal, and press **Generate** for the Export Name. Rewording a descriptive name is not the fix: a slightly less obvious description is the same disclosure. See [Compliance for audiences](/docs/audiences/compliance). ### Do my conditions reach the destination? [#do-my-conditions-reach-the-destination] > No. You can build an audience on any criteria your data supports, and no condition, property, or criterion is ever sent. A sync sends the Export Name and the enabled hashed identifiers for each member. ### Do you filter out people who did not consent to advertising? [#do-you-filter-out-people-who-did-not-consent-to-advertising] > Nothing filters an audience on consent for you. A sync and a CSV both send the audience as you defined it. Add a visitor condition: Rejected Consent Categories **does not contain** `advertising` to exclude recorded rejections, or Accepted Consent Categories **contains** `advertising` if you need affirmative opt-in. See [Compliance for audiences](/docs/audiences/compliance). ### What exactly leaves Ours Privacy on a sync? [#what-exactly-leaves-ours-privacy-on-a-sync] > The audience's Export Name and the enabled SHA-256 hashed identifiers for each member. The exact identifier groups depend on the destination. A sync does not send audience conditions or your internal audience name. ### Who on my team can accept the data-sharing terms? [#who-on-my-team-can-accept-the-data-sharing-terms] > Accepting the terms and selecting destinations are governed by permissions, and the acknowledgement is a statement about your organization's authority and lawful basis. Ask your account administrator about who should hold that access. *** ## Building audiences [#building-audiences] ### What is the difference between Visitor Properties and Event Behavior? [#what-is-the-difference-between-visitor-properties-and-event-behavior] > Visitor Properties filter on attributes: consent, attribution, location, identity, custom properties. Event Behavior filters on what somebody did, as a count inside a rolling day window. A visitor has to satisfy both sections. See [Visitor conditions](/docs/audiences/visitor-conditions) and [Event conditions](/docs/audiences/event-conditions). ### How do I exclude people who already converted? [#how-do-i-exclude-people-who-already-converted] > Add an event condition for the conversion event with a count of **is exactly 0**. Combined with an interest signal, that is the standard retargeting shape and the single most useful pattern in the product. See [The zero-count pattern](/docs/audiences/event-conditions). ### My page view condition matches almost everybody. Why? [#my-page-view-condition-matches-almost-everybody-why] > Because every page on your site fires a page view. Add a nested condition on the page URL so only the occurrences you care about count toward the total. ### Should I use the current or the initial attribution properties? [#should-i-use-the-current-or-the-initial-attribution-properties] > Initial, for almost everything. The initial values record how the visitor first found you and do not change on later visits, which is what you want when you are segmenting by acquisition channel. The current values describe the most recent session. ### Can I build an audience from an experiment variant? [#can-i-build-an-audience-from-an-experiment-variant] > Yes. Use **From experiment** in the Event Behavior card and it fills in the impression event and the variant filter for you. See [Experimentation](/docs/experimentation). ### How fresh is the data? [#how-fresh-is-the-data] > Event data becomes queryable within about fifteen minutes of collection, so an audience built on this morning's behavior works this afternoon. ### Is a preview count exact? [#is-a-preview-count-exact] > It is an estimate of how many visitors match, and it is the right number for sanity-checking a definition. It is not a prediction of how many people a platform will recognize, which is always lower. See [Previewing an audience](/docs/audiences/previewing-an-audience). ### Can I copy an audience? [#can-i-copy-an-audience] > Yes. Duplicate it from the audience list, then edit the copy. It is the fastest way to build a set of related audiences with different windows or different exclusions. *** ## Exporting [#exporting] ### What are the three export formats for? [#what-are-the-three-export-formats-for] > **All Fields** is raw values and every visitor column, for CRM uploads, warehouse loads, and analysis. **Google Ads Format** and **Facebook Ads Format** are hashed and normalized to each platform's specification, for uploading by hand. See [Exporting a CSV](/docs/audiences/exporting-csv). ### Why does my export say only some rows had matchable data? [#why-does-my-export-say-only-some-rows-had-matchable-data] > Because a platform can only match on an email address or a phone number. A visitor with a city and a name but no identifier cannot be matched by anybody, so those rows are filtered out of the file rather than shipped as unmatched. A large gap is telling you about your data collection, not about the export. Adding an **Email is not null** condition makes the deliverable size visible in Preview instead. ### How long can I download an export? [#how-long-can-i-download-an-export] > A finished export stays available to re-download for a limited window, then drops off the **Recent Exports** list and you run it again. Each download link is also issued fresh when you press **Download** and an individual link is short-lived, so if a link stops working, go back to the audience and press Download again rather than reusing an old URL. See [Data Retention](/docs/data-retention). ### Can I export several audiences at once? [#can-i-export-several-audiences-at-once] > Yes. Select them in the audience list and export. Each produces its own file in the format you choose, named after its own Export Name. ### Why is Export CSV greyed out? [#why-is-export-csv-greyed-out] > The button needs three things: a name, at least one condition, and nothing unsaved. Save your changes and it becomes available. *** ## Syncing [#syncing] ### How often does a sync run? [#how-often-does-a-sync-run] > Daily, a little after midnight UTC. There is nothing to schedule and nothing to trigger. ### Does a sync add people, or replace the list? [#does-a-sync-add-people-or-replace-the-list] > It depends on the destination. [Vibe CTV Audiences](/docs/audiences/vibe-ctv-audiences) and [Facebook Custom Audiences](/docs/audiences/facebook-custom-audiences) replace the full membership every run. [Google Customer Match](/docs/audiences/google-customer-match) refreshes members for one day at a time. [MNTN Audiences](/docs/audiences/mntn-audiences) adds or updates the members it receives and does not automatically remove members who leave the audience. ### Which platforms can I sync to? [#which-platforms-can-i-sync-to] > [Vibe CTV Audiences](/docs/audiences/vibe-ctv-audiences), [MNTN Audiences](/docs/audiences/mntn-audiences), [Facebook Custom Audiences](/docs/audiences/facebook-custom-audiences), and [Google Customer Match](/docs/audiences/google-customer-match). ### Can I sync an audience to a destination I already use for events? [#can-i-sync-an-audience-to-a-destination-i-already-use-for-events] > No. Audience syncing works with [Audience Destinations](/docs/audiences/audience-destinations) only. Event destinations receive events as they happen and have no concept of membership, so they are not offered in the sync card even when the same company appears in both lists. ### Why did my sync get skipped? [#why-did-my-sync-get-skipped] > The usual reasons are that the destination is disabled, the audience is not published, or the destination has not been included in a published version of your destination settings. An empty membership is also refused rather than sent. For destinations that replace membership, this prevents clearing the audience on the platform. ### My audience synced but the platform shows far fewer people. Is something broken? [#my-audience-synced-but-the-platform-shows-far-fewer-people-is-something-broken] > Almost certainly not. A platform matches the hashed identifiers it receives only against people already in its own graph, so the audience there is often smaller than what you delivered. A low match rate produces no error anywhere: the upload succeeds and the platform reports the audience as active. Check the platform's own match figure, and check the delivered count in Ours Privacy to separate a matching problem from a deliverability one. ### How long until I can target a synced audience? [#how-long-until-i-can-target-a-synced-audience] > After a sync lands, a platform may take a day or two to finish processing an audience update before it is usable. That is platform-side and is not something Ours Privacy reports on. Platforms also enforce minimum sizes: Meta's guidance is at least 1,000 people and Google recommends at least 5,000 for a Customer Match list. ### How do I stop a sync? [#how-do-i-stop-a-sync] > Remove the destination from the **Sync to Destinations** card. The list already on the platform stays until you delete it there. Removing the last destination clears the data-sharing acknowledgement, so turning the sync back on later means accepting the terms again rather than inheriting a decision from months ago. ### I renamed the audience and cannot find it in the ad platform. Why? [#i-renamed-the-audience-and-cannot-find-it-in-the-ad-platform-why] > The platform shows the **Export Name**, not your internal name, and renaming changes the label going forward. Copy the platform-facing name from the **Sync to Destinations** card. Rename before attaching campaigns rather than after, where you have the choice. *** ## Access and limits [#access-and-limits] ### How many audiences can I have? [#how-many-audiences-can-i-have] > Your plan sets a limit on audiences per account. When you reach it, delete audiences you no longer use or contact your account representative about raising it. ### Who can create and publish audiences? [#who-can-create-and-publish-audiences] > Access is granted per action, so viewing, creating, editing, previewing, publishing, and deleting can be granted separately. Selecting sync destinations and accepting the data-sharing terms are governed the same way. Ask your account administrator about your access. ### Is Audience Builder generally available? [#is-audience-builder-generally-available] > Yes. [Audience Performance](/docs/attribution/audience-performance), the reporting product that measures how audiences convert, is a separate feature in Public Beta. ### Can I create audiences through the API? [#can-i-create-audiences-through-the-api] > Audience membership is not exposed through the Platform API today. See [Platform API](/docs/platform-api) for what is available. *** ## Next Steps [#next-steps] * **[Audience concepts](/docs/audiences/concepts)** for the model behind these answers. * **[Building an audience](/docs/audiences/building-an-audience)** to build your first one. * **[Recipes](/docs/audiences/recipes)** for worked configurations. * **[Compliance for audiences](/docs/audiences/compliance)** for the obligations that come with sharing one. Need help? Contact [support@oursprivacy.com](mailto:support@oursprivacy.com). Google Customer Match sends the members of an Ours Privacy audience to a Customer Match list in Google Ads. Ours Privacy submits each daily membership update for Google to process. *** ## Before you start [#before-you-start] * A Google Ads account eligible for Customer Match and authorized to use customer data. * A Google Cloud project with the Google Data Manager API enabled. * Your own Google OAuth client in that project. The client must be configured for the Google Data Manager sensitive permission that Ours Privacy requests during connection. * The Ours Privacy production redirect URI, `https://app.oursprivacy.com/integrations`, added to the OAuth client's authorized redirect URIs. * A Customer ID for the Google Ads account that owns the list. If it is managed through an MCC, you also need the Manager Account ID. * An audience with about 5,000 matchable members. Google may accept a smaller upload, but it may not be usable for targeting. You do not need a Google Ads developer token for this destination. Ours Privacy does not reuse an Ours-owned Google Ads token. *** ## Set up the destination [#set-up-the-destination] 1. In **Destinations**, add **Google Customer Match**. 2. Enter your Google OAuth Client ID and Google OAuth Client Secret. Ours Privacy does not use an Ours-owned OAuth app or Google Ads developer token for this destination. 3. Select **Connect Google Data Manager** and complete the Google sign-in flow. 4. Enter the Google Ads Customer ID. Add the Manager Account ID only when the account is accessed through an MCC. 5. Choose the identifier groups you authorize Ours Privacy to send. Every group starts off. 6. Save and publish the destination. Ours Privacy stores the OAuth client secret as a secret setting and does not display it again after save. If you connected this destination before the Data Manager migration, reconnect it so Google can grant the required permission. *** ## Identifier choices [#identifier-choices] You choose whether to send: * Email * Phone * Postal address: first name, last name, country, and postal code Each enabled value is normalized for Google and hashed with SHA-256 before upload. Members with no usable enabled identifier are skipped. Google does not receive your audience conditions or internal audience name. *** ## Sync behavior and eligibility [#sync-behavior-and-eligibility] Ours Privacy creates one Customer Match list for each attached audience and submits membership updates daily. List membership is configured to expire one day after its last refresh, so members who leave the audience age out after the next daily cycle. A missed sync can temporarily reduce the active list. Google processes Customer Match asynchronously. Ours Privacy reports submission errors, including common eligibility and terms errors, but Google Ads determines when the list becomes usable and how many members it matches. Keep the Export Name neutral. It is visible in Google Ads and must not describe a sensitive characteristic. For EEA audiences, ensure your setup and audience criteria meet Google's consent requirements. *** ## Next Steps [#next-steps] * **[Audience Destinations](/docs/audiences/audience-destinations)** for how audience syncing works. * **[Syncing to destinations](/docs/audiences/syncing-to-destinations)** to attach this destination to an audience. * **[Audience Builder](/docs/audiences/building-an-audience)** to build and export audiences now. Need help? Contact [support@oursprivacy.com](mailto:support@oursprivacy.com). Audiences let you describe a group of people using the data you already collect, see who matches, and then act on that group: download it as a CSV your ad platform accepts, or have Ours Privacy send its membership to an advertising platform every day. This is how retargeting and remarketing campaigns get built here. Conditions can describe who somebody is (consent, attribution, location, your own custom properties) and what they did on your site (pages viewed, forms submitted, events they never fired). Audiences exist because the ordinary way to do this in healthcare marketing leaks. Exporting a spreadsheet called `diabetes-nonconverters-q3` into Meta discloses a health condition to Meta in the file name alone, before anyone looks at a row. Ours Privacy keeps your descriptive name private, sends a separate meaningless name to the platform, and sends only the hashed identifiers enabled for that destination. Audiences Audience Builder list showing fictional Northside Women's Health audiences in the Ours Privacy dashboard. > **Important:** Advertising platforms are not HIPAA business associates. Meta, Google, and Vibe do not sign BAAs, and their terms prohibit uploading protected health information or consumer health data. Read [Compliance for audiences](/docs/audiences/compliance) before you sync an audience anywhere. *** ## Why use Ours Privacy Audiences [#why-use-ours-privacy-audiences] * **The name you use internally never leaves.** Every audience carries a private **Name** you write for your team and a separate **Export Name** that is the only label a platform or a CSV ever shows. See [Export names](/docs/audiences/export-names). * **Behavior, not just attributes.** Combine visitor properties with event conditions such as "viewed the appointment page at least twice in 30 days and never reached the confirmation page." See [Event conditions](/docs/audiences/event-conditions). * **Check before you commit.** Preview returns an estimated count and a sample of matching visitors, so a mistaken condition shows up before an upload does. See [Previewing an audience](/docs/audiences/previewing-an-audience). * **Two ways out, one definition.** The same audience can be downloaded as a CSV formatted for Google Ads or Meta, or synced automatically to an [Audience Destination](/docs/audiences/audience-destinations). You do not maintain two definitions. * **Keep targeting current.** Every sync re-evaluates the audience daily. Whether people who stop matching are removed depends on the destination. * **What you preview is what you send.** An audience is sent exactly as you defined it, with nothing filtered out on the way, so consent belongs in the conditions if it bears on who may be shared. See [Compliance for audiences](/docs/audiences/compliance). *** ## How it fits together [#how-it-fits-together] 1. **Create an audience** and give it a private name plus an Export Name (use **Generate** if you would rather not invent one). 2. **Add conditions** in **Visitor Properties**, **Event Behavior**, or both. An audience needs at least one condition before it can do anything. 3. **Preview** to see the estimated size and a sample of who matches, then adjust the conditions until the group looks right. 4. **Activate it**: download a CSV in the format your platform expects, or select Audience Destinations and let Ours Privacy send membership daily. *** ## Key pages [#key-pages] * **[Audience concepts](/docs/audiences/concepts)**: what an audience is, what published means, and the difference between exporting and syncing. * **[Building an audience](/docs/audiences/building-an-audience)**: the walkthrough, from creating one to activating it. * **[Visitor conditions](/docs/audiences/visitor-conditions)**: the properties you can filter on and every operator available. * **[Event conditions](/docs/audiences/event-conditions)**: counts, rolling time windows, event property filters, and the never-did-this pattern. * **[Previewing an audience](/docs/audiences/previewing-an-audience)**: how to read the estimate and the sample, and what a preview does not tell you. * **[Export names](/docs/audiences/export-names)**: the second name, why it exists, how to generate one, and how to change it safely. * **[Compliance for audiences](/docs/audiences/compliance)**: the data-sharing terms, naming, applying consent, what platforms receive, and what stays with you. * **[Exporting a CSV](/docs/audiences/exporting-csv)**: the three export formats, what gets hashed, and the matched-row count. * **[Syncing to destinations](/docs/audiences/syncing-to-destinations)**: set up a daily sync, read a sync result, and stop one. * **[Audience Destinations](/docs/audiences/audience-destinations)**: which platforms can receive an audience and how the daily sync behaves. * **[Targeting strategies](/docs/audiences/targeting-strategies)**: exclusion audiences, retargeting, lookalike seeds, and layering them. * **[Recipes](/docs/audiences/recipes)**: worked audience configurations you can copy, grouped by goal. * **[Audience FAQs](/docs/audiences/faqs)**: sizing, match rates, timing, consent, naming, and access questions. *** ## Works with the rest of the platform [#works-with-the-rest-of-the-platform] * **[Cookie Consent](/docs/cookie-consent)**: consent categories become conditions, so an audience can require an accepted advertising category rather than only excluding rejections. * **[Web Analytics](/docs/web-analytics)**: every event you already collect is available as an event condition, with no extra instrumentation. * **[Experimentation](/docs/experimentation)**: build an audience of the visitors who saw one variant, using **From experiment** in the Event Behavior section. * **[Audience Performance](/docs/attribution/audience-performance)**: measure how an audience-shaped group converts and what revenue it drove. * **[Short Links](/docs/short-links)**: target visitors who scanned a QR code or arrived through a specific link or campaign. * **[Destinations](/docs/destination-overview)**: event destinations receive events; Audience Destinations receive membership. Most accounts use both. *** ## Availability [#availability] Audiences are subject to a per-account audience limit. If you have reached your limit and need more audiences, contact your account representative. Creating, editing, previewing, and exporting are each governed by their own permission, so ask your account administrator if an action is disabled for you. Audiences are built and activated in the dashboard. There is no SDK to install, and building an audience does not require any instrumentation beyond the events and visitor properties you already collect. Audience membership is not exposed through the [Platform API](/docs/platform-api) today, though the [audience conversion report](/docs/platform-api/attribution-conversion) is available there. *** ## Need help? [#need-help] Reach out to [support@oursprivacy.com](mailto:support@oursprivacy.com) with any questions about audiences. Destinations Use this page to connect an Ours Privacy audience to MNTN for connected TV targeting. Ours Privacy sends the matchable members of your audience to a MNTN segment once per day, a little after midnight UTC. *** ## Before you start [#before-you-start] * An active MNTN advertiser account with the Audience integration enabled. * An Audience API key from the MNTN Integrations page for the account that will target the segment. * An [Audience Builder audience](/docs/audiences/building-an-audience) with members who have email addresses or international-format phone numbers. * A neutral Export Name. MNTN displays this name, so avoid names that disclose audience criteria. ## Set up MNTN Audiences [#set-up-mntn-audiences] 1. Add **MNTN Audiences** from [Destinations](https://app.oursprivacy.com/destinations). 2. Enter the MNTN API key from the MNTN Integrations page. 3. Turn on **Send hashed email**, **Send hashed phone**, or both. Ours Privacy hashes enabled identifiers with SHA-256 before sending them to MNTN. 4. Save and publish the destination settings. 5. Open the audience you want to target, set its Export Name, accept the data-sharing terms, and select MNTN Audiences in **Sync to Destinations**. ## What MNTN receives [#what-mntn-receives] MNTN receives your Export Name and the enabled, matchable identifiers. Ours Privacy sends hashed email addresses and hashed phone numbers only. It does not send your audience conditions, internal audience name, or raw identifier values. Each nightly run adds new members to the MNTN segment and updates members Ours Privacy has already sent. Removing someone from your Ours Privacy audience does not automatically remove them from MNTN. Review campaigns and segments regularly, then remove members in MNTN when that is needed. Members without an enabled usable identifier are skipped. MNTN decides which hashed identifiers it can match to people in its own graph, so its available audience size can be lower than the delivered count in Ours Privacy. Changing an identifier setting affects future syncs only. Turning off an identifier does not remove the matching identifier or member data MNTN received earlier. *** ## Next Steps [#next-steps] * [Audience Destinations](/docs/audiences/audience-destinations) for the audience sync workflow. * [Syncing to Destinations](/docs/audiences/syncing-to-destinations) for Export Names, terms, and delivery history. * [MNTN](/docs/mntn) to send MNTN campaign events. * [Audience Builder](/docs/audiences/building-an-audience) to create and refine audiences. Need help? Contact [support@oursprivacy.com](mailto:support@oursprivacy.com). Use this page to check that an audience matches the people you meant before you export or sync it. Preview is the only feedback loop between writing conditions and sending data somewhere, so it is worth reading properly rather than glancing at the number. > **Important:** Advertising platforms are not HIPAA business associates and do not sign BAAs. Read [Compliance for audiences](/docs/audiences/compliance) before sending an audience to any platform. *** ## Running a preview [#running-a-preview] 1. Save your changes. Preview runs against the saved definition, so the button waits until nothing is unsaved. 2. Press **Preview** in the **Audience Preview** card. 3. Read the estimated count and the sample table. 4. Adjust conditions, save, and press **Refresh Preview** to run it again. Preview runs a query over your data and takes a moment on larger audiences. It does not create anything, send anything, or count against any limit. *** ## What you get [#what-you-get] **An estimated visitor count** shown as an approximate figure. Treat it as the right order of magnitude rather than an exact number, and use it for the questions that matter: is this audience roughly the size I expected, and is it big enough to be usable. **A sample of matching visitors** in a table with email, first name, last name, city, state, country, first seen, last seen, and consent. The sample is there to answer a different question from the count: do these look like the people I meant? Read both. A plausible count with an obviously wrong sample is the most common way a broken audience passes inspection. *** ## Reading the result [#reading-the-result] ### The count is much larger than expected [#the-count-is-much-larger-than-expected] Almost always an event condition with no nested filter. A page view condition with no URL filter counts every page on your site, so "viewed a page at least twice" matches most returning visitors. Add a nested condition narrowing it to the pages that indicate the interest you care about. See [Event conditions](/docs/audiences/event-conditions). The second most common cause is an OR connector where you meant AND. ### The count is much smaller than expected, or zero [#the-count-is-much-smaller-than-expected-or-zero] Work through these in order. * **Mismatched time windows.** Two conditions in the same funnel using different day counts can describe a sequence almost nobody performed. Align them. * **A condition that is exactly right and matches nothing.** An event name with a typo, a URL fragment that does not appear on your site, or a date value that is not a valid date all silently make a condition false rather than raising an error. * **Too many ANDs.** Each one narrows. Remove them one at a time to find which one collapses the audience. * **A consent condition that is stricter than your data.** Requiring an accepted advertising category only matches visitors who actively accepted it. If most of your traffic predates your consent banner, that is a small group. ### The count looks right but the sample does not [#the-count-looks-right-but-the-sample-does-not] Look at what the sample rows have in common. Visitors from a country you did not intend, or all with a first-seen date years ago, point at a missing condition rather than a wrong one. ### Most sample rows have no usable identifier [#most-sample-rows-have-no-usable-identifier] This one matters more than it looks. A synced audience matches on the destination's enabled identifiers, so members without one are skipped on delivery. An audience that previews at 40,000 visitors and has an enabled identifier on a tenth of them delivers a tenth of that. Add a visitor condition requiring a destination-supported identifier to be not null and preview again. That number is your realistic deliverable size. See [Audience Destinations](/docs/audiences/audience-destinations). *** ## What a preview does not tell you [#what-a-preview-does-not-tell-you] **Whether the platform will match anyone.** Preview counts the people in your data. A platform matches the hashed identifiers it receives only against people it already recognizes, and the audience there will be smaller. Nothing about the gap produces an error on either side. **Whether the audience is large enough for the platform.** Platform minimums are the platform's rule, not ours. Meta's guidance for a customer list is at least 1,000 people; Google recommends uploading at least 5,000 members for a Customer Match list to have a reasonable chance of serving. See the individual destination pages. **What the sync will send.** Preview shows the audience as defined, and a sync sends the same population. Nothing is filtered out on the way, so the count you see is the count that uploads. See [Compliance for audiences](/docs/audiences/compliance). **How fresh the data is.** Events become queryable within about fifteen minutes of collection, so a preview reflects behavior up to a few minutes ago rather than this second. *** ## Habits worth having [#habits-worth-having] **Preview before every export and every sync change.** It costs a moment and catches the mistakes that are expensive to notice later. **Start broad, then narrow.** Build the simplest version of the audience, preview it, and add one condition at a time. The count after each change tells you what that condition did, which is information you lose if you add five at once. **Write down what you expected.** A count only means something against an expectation. "This should be a few thousand people" turns the preview into a test rather than a number. *** ## Next Steps [#next-steps] * **[Visitor conditions](/docs/audiences/visitor-conditions)** and **[Event conditions](/docs/audiences/event-conditions)** to adjust what you built. * **[Exporting a CSV](/docs/audiences/exporting-csv)** to download the audience once it looks right. * **[Syncing to destinations](/docs/audiences/syncing-to-destinations)** to send it daily instead. * **[Audience FAQs](/docs/audiences/faqs)** for sizing and match-rate questions. Need help? Contact [support@oursprivacy.com](mailto:support@oursprivacy.com). Worked audience configurations for goals customers actually ask for. Build each one in the [Audience Builder](https://app.oursprivacy.com/marketing-center/audience-builder) by setting the conditions shown, then preview before you activate. > **Important:** Advertising platforms are not HIPAA business associates and do not sign BAAs. Read [Compliance for audiences](/docs/audiences/compliance) before sending an audience to any platform. The event names below (`Page View`, `Form Submitted`, `Purchase`) stand in for whatever your account actually collects. Substitute your own. For what each operator means, see [Visitor conditions](/docs/audiences/visitor-conditions) and [Event conditions](/docs/audiences/event-conditions). *** ## Stop paying for people you already have [#stop-paying-for-people-you-already-have] ``` Name: Converters, last 90 days Export Name: amber-harbor-drum (press Generate) Event Behavior Event: Purchase Count: is greater than or equal to 1 Window: 90 days ``` Attach this audience as an **excluded** or **negative** audience on your acquisition campaigns in the ad platform. Ours Privacy sends the membership; the platform applies the exclusion. Set the window to how long somebody stays a customer, not to a reporting period. If your product is bought once a year, 90 days is too short. ``` Name: Already booked an appointment, last 60 days Export Name: copper-lantern-cove Event Behavior Event: Appointment Confirmed Count: is greater than or equal to 1 Window: 60 days ``` Build one of these per live campaign, matched to the action the campaign asks for. An ad asking a current patient to become a patient is a worse outcome than a wasted impression. *** ## Retargeting people who did not finish [#retargeting-people-who-did-not-finish] ``` Name: Started booking form, did not complete, 14 days Export Name: bright-compass-trail Event Behavior (combine with AND) Event: Form Started Count: is greater than or equal to 1 Window: 14 days Event: Appointment Confirmed Count: is exactly 0 Window: 14 days ``` The second condition is the one that matters. Without it you are paying to retarget people who completed the booking. Match the two windows. A 14-day intent window against a 30-day conversion window means somebody who booked 20 days ago is still in the audience. ``` Name: Viewed pricing, no purchase, 30 days Export Name: Q3-A Event Behavior (combine with AND) Event: Page View Count: is greater than or equal to 1 Window: 30 days Nested: Page URL contains /pricing Event: Purchase Count: is exactly 0 Window: 30 days ``` The nested URL condition is not optional here. A bare page view condition matches nearly every visitor to your site, because every page fires one. ``` Name: Three or more visits, no conversion, 60 days Export Name: blue-harbor Event Behavior (combine with AND) Event: Page View Count: is greater than or equal to 3 Window: 60 days Event: Purchase Count: is exactly 0 Window: 60 days ``` Sustained interest is a more durable signal than a single visit, and this audience is usually large enough to clear platform minimums when a single-page audience is not. *** ## Layering behavior with who someone is [#layering-behavior-with-who-someone-is] ``` Name: Paid search intent, no conversion, 30 days Export Name: north-star Visitor Properties Initial UTM Medium is cpc Event Behavior (combine with AND) Event: Page View Count: is greater than or equal to 1 Window: 30 days Nested: Page URL contains /services Event: Purchase Count: is exactly 0 Window: 30 days ``` Use the **initial** attribution properties rather than the current ones. Initial values record how the visitor first found you and do not change on later visits. Both sections apply, so a visitor has to satisfy the visitor property and every event condition. ``` Name: High intent, serviceable states Export Name: silver-maple Visitor Properties (combine with AND) State is found in CA, OR, WA Email is not null Event Behavior Event: Page View Count: is greater than or equal to 1 Window: 30 days Nested: Page URL contains /locations ``` The **Email is not null** condition is doing quiet work: it removes visitors a platform could never match anyway, which makes the previewed size much closer to the number you will actually deliver. See [Previewing an audience](/docs/audiences/previewing-an-audience). *** ## Audiences for lookalike seeds [#audiences-for-lookalike-seeds] ``` Name: Repeat purchasers, seed for lookalikes Export Name: list-north Event Behavior Event: Purchase Count: is greater than or equal to 2 Window: 180 days ``` Seed quality beats seed size, up to a point. A seed of repeat purchasers models a better customer than a seed of everyone who ever bought, but a platform still needs enough people to find a pattern: Meta's guidance is at least 1,000 and Google recommends at least 5,000. If Preview comes back under those figures, loosen the count or widen the window rather than accepting a seed too small to work. Two things to do in the platform after this syncs. Build the lookalike from it, then **exclude this same seed audience from the lookalike campaign** so you are not paying to re-reach the customers you modeled on. *** ## Consent and compliance shapes [#consent-and-compliance-shapes] ``` Name: Opted in to advertising, high intent, 30 days Export Name: clever-orbit-basin Visitor Properties Accepted Consent Categories contains advertising Event Behavior Event: Page View Count: is greater than or equal to 1 Window: 30 days Nested: Page URL contains /services ``` Nothing filters an audience on consent for you, so this condition is what applies it. Requiring an **accepted** category is stricter than excluding a rejected one, because someone who was never asked is not a rejection. See [Compliance for audiences](/docs/audiences/compliance). This is also the condition to add when you plan to export a CSV and upload it to a platform by hand, since a download is not gated on consent. ``` Name: Do not contact Export Name: humble-cedar-vault Event Behavior Event: Contact Preference Updated Count: is greater than or equal to 1 Window: 365 days Nested: Preference is do_not_contact ``` The point of this audience is that it is only ever used as an exclusion. Syncing it keeps it current, which is the whole reason to build it rather than maintaining a list by hand. *** ## An audience for a CRM or a warehouse [#an-audience-for-a-crm-or-a-warehouse] ``` Name: Q3 pipeline review, engaged no purchase Export Name: Q3-review Visitor Properties Email is not null Event Behavior (combine with AND) Event: Page View Count: is greater than or equal to 2 Window: 90 days Event: Purchase Count: is exactly 0 Window: 90 days Export format: All Fields ``` The all-fields export gives you raw values and every visitor column, including first-touch attribution and click IDs, which is what makes it useful for analysis and useless for uploading to a platform. It is also the only format containing raw email addresses, so it is the file to be most careful with. Note the Export Name still lands in the file name, which is the reason to keep it uninformative even for an internal export. See [Exporting a CSV](/docs/audiences/exporting-csv). *** ## Next Steps [#next-steps] * **[Building an audience](/docs/audiences/building-an-audience)** for the interface these configurations map to. * **[Targeting strategies](/docs/audiences/targeting-strategies)** for why these shapes work. * **[Previewing an audience](/docs/audiences/previewing-an-audience)** to check a configuration before activating it. * **[Audience FAQs](/docs/audiences/faqs)** for the questions these recipes tend to raise. Need help? Contact [support@oursprivacy.com](mailto:support@oursprivacy.com). Use this page to set up a daily audience sync, read the result, and stop one. For downloading a file by hand instead, see [Exporting a CSV](/docs/audiences/exporting-csv). > **Important:** Advertising platforms are not HIPAA business associates and do not sign BAAs. Read [Compliance for audiences](/docs/audiences/compliance) before setting up a sync. *** ## Before you start [#before-you-start] * **An Audience Destination configured in your account.** Syncing works with [Audience Destinations](/docs/audiences/audience-destinations) only, not with every destination connected to your account. Event destinations receive events, not membership, and are not offered here. Add one from [Destinations](https://app.oursprivacy.com/destinations) first. * **An audience whose members have identifiers enabled for the destination.** Each destination decides which identifiers it can use. Members without an enabled usable identifier are skipped. * **An Export Name on the audience.** This is the label the platform displays, and it is required. See [Export names](/docs/audiences/export-names). *** ## Setting up the sync [#setting-up-the-sync] Everything happens in the **Sync to Destinations** card on the audience. 1. **Set the Export Name** if you have not already. Press **Generate** for a neutral one. The card shows the exact form the destinations will see and lets you copy it, which is what you will search for in the platform's interface later. 2. **Read and accept the data-sharing terms** shown in the card. They cover the four points on [Compliance for audiences](/docs/audiences/compliance), and the confirmation you tick is a statement that you have the authority and a lawful basis to share this audience. 3. **Select the Audience Destinations** you want the audience sent to. You can select more than one, and each gets its own independent sync. 4. **Save.** The audience then syncs daily, a little after midnight UTC. Nothing else to schedule and nothing to trigger. If the card says you have no Audience Destinations yet, add one from [Destinations](https://app.oursprivacy.com/destinations) and come back. *** ## Destination readiness [#destination-readiness] Each destination in the card shows whether it can actually receive an audience today. **Available** destinations sync normally. **Not available for sync** covers destinations that receive events rather than membership. [Vibe CTV Audiences](/docs/audiences/vibe-ctv-audiences), [MNTN Audiences](/docs/audiences/mntn-audiences), [Facebook Custom Audiences](/docs/audiences/facebook-custom-audiences), and [Google Customer Match](/docs/audiences/google-customer-match) are available today. *** ## What each run sends [#what-each-run-sends] Every destination receives the audience's **Export Name** and the identifiers you enable in that destination's settings. Identifiers are normalized and hashed with SHA-256 before they leave Ours Privacy. The platform does not receive your audience conditions or internal audience name. Members with no usable enabled identifier are skipped. Membership behavior depends on the destination. [Vibe CTV Audiences](/docs/audiences/vibe-ctv-audiences) and [Facebook Custom Audiences](/docs/audiences/facebook-custom-audiences) replace full membership every run, so removals happen automatically. [Google Customer Match](/docs/audiences/google-customer-match) refreshes members for one day at a time. [MNTN Audiences](/docs/audiences/mntn-audiences) adds or updates the members it receives, and does not automatically remove members who leave the audience. A new audience appears after its first successful run, not the moment you attach it. A sync sends the audience as you defined it, and does not filter on consent. Add a consent condition to the audience if one applies. See [Compliance for audiences](/docs/audiences/compliance). *** ## When a run is skipped [#when-a-run-is-skipped] A sync is skipped rather than failed when the destination is **Disabled**, when the audience is not published, or when the destination has not been included in a published version of your destination settings yet. That last one catches people out: audience syncs read your published destination settings, so a destination you configured but never published is skipped. See [Published Versions](/docs/version-management). An empty membership is refused rather than sent. If every member lacks an enabled usable identifier, the run fails with that reason. *** ## Reading the result [#reading-the-result] Ours Privacy records, for each run, how many members were delivered against how many were in the audience. Those two numbers are the diagnostic that matters. A large gap means most of the audience had no enabled identifier to match on, and the fix is in your data collection, destination settings, or audience conditions rather than at the platform. See [Previewing an audience](/docs/audiences/previewing-an-audience). What the numbers cannot tell you is how many people the platform recognized. A platform matches the hashed identifiers it receives only against people already in its own graph, so the audience there will be smaller than what you delivered, and a low match rate produces no error anywhere: the upload succeeds and the platform reports the audience as active. Check the platform's own interface for its match figure. See [Audience Destinations](/docs/audiences/audience-destinations). *** ## Changing or stopping a sync [#changing-or-stopping-a-sync] **Add or remove destinations** in the same card at any time. Removing one stops the audience being sent there; the list already on the platform stays until you delete it there. **Removing the last destination clears the acknowledgement.** Turning the sync back on later means reading and accepting the data-sharing terms again, rather than inheriting a decision from months ago. **Renaming the Export Name** changes the label the platform displays going forward, so if campaigns are already attached to the audience, you will be looking for a different name next time. Rename before attaching campaigns where you have the choice. **Deleting the audience** should be preceded by stopping the sync, so it stops being sent before the definition disappears. *** ## Practical notes [#practical-notes] **Review synced audiences on a schedule.** A daily sync runs until somebody stops it. An audience built for a campaign that ended is still being sent every night. **One audience, several platforms.** Attaching the same audience to more than one destination is normal, and each sync is independent. A platform that rejects one upload cannot hold up the others. **Platforms take their own time.** After a sync lands, a platform may take up to a day or two to finish processing an audience update before it is usable for targeting. That is platform-side and is not something Ours Privacy reports on. **Search for the Export Name.** When you go into the platform to attach the audience to a campaign, your internal name is not there. Copy the platform-facing name from the card. *** ## Next Steps [#next-steps] * **[Audience Destinations](/docs/audiences/audience-destinations)** for how the daily sync behaves and which platforms support it. * **[Facebook Custom Audiences](/docs/audiences/facebook-custom-audiences)** and **[Google Customer Match](/docs/audiences/google-customer-match)** for destination setup. * **[Compliance for audiences](/docs/audiences/compliance)** for the terms, naming, and applying consent. * **[Targeting strategies](/docs/audiences/targeting-strategies)** for what to sync and why. Need help? Contact [support@oursprivacy.com](mailto:support@oursprivacy.com). Use this page to decide what to build. The mechanics are covered in [Building an audience](/docs/audiences/building-an-audience); this page is about which audiences are worth the effort and which patterns quietly waste money. Retargeting and remarketing are the same thing here: the patterns below apply either way. > **Important:** Advertising platforms are not HIPAA business associates and do not sign BAAs. Read [Compliance for audiences](/docs/audiences/compliance) before sending an audience to any platform. *** ## Start with exclusion, not acquisition [#start-with-exclusion-not-acquisition] The instinct is to build audiences of people to reach. The higher-return first audience is usually a list of people to stop reaching. Every advertising platform will happily keep showing an acquisition ad to somebody who converted last week. The platform has no idea they converted, because conversion happened on your site or in your clinic rather than in the ad account. So you pay for impressions against people who are already customers, and the people who see them are the ones most likely to click, which makes the campaign look like it is working. An exclusion audience fixes it in one move. Build an audience of people who completed the action, then attach it as a negative or excluded audience in the ad platform. Ours Privacy sends the membership; the platform decides what to do with it, and every major platform supports using an audience as an exclusion. **The pattern.** One event condition: the conversion event, count **is greater than or equal to** 1, over a window long enough to cover how long somebody stays a customer. For a booked appointment that might be 90 days. For a repeat purchase it might be 30. **Why a daily sync matters here.** Yesterday's converters need to be out of today's targeting. A CSV you uploaded last month excludes last month's customers and nobody since. See [Syncing to destinations](/docs/audiences/syncing-to-destinations). Worth knowing: not every platform gives you a built-in exclusion control, so on some of them the equivalent is a "has not yet converted" audience instead of an exclusion. In Ours Privacy the zero-count pattern is a first-class condition, so you can express either shape. See [The zero-count pattern](/docs/audiences/event-conditions). *** ## Exclude within a funnel, not only at the end [#exclude-within-a-funnel-not-only-at-the-end] The same logic applies at every step, and this is where most of the upside is. If you are running a campaign to get people to book, exclude people who already booked. If you are running a campaign to get people to complete an intake form, exclude people who completed it. Somebody who is one step further down the funnel than your ad is asking for is somebody the ad is wasted on, and the ad may be actively unhelpful: an ad asking a current patient to become a patient is a bad experience, not just a bad impression. A useful audit: list your live campaigns, and for each one write down the action it is asking for. Every one of those actions is an exclusion audience you probably do not have yet. *** ## Retargeting the right window [#retargeting-the-right-window] A retargeting audience is people who showed intent and did not finish. The failure mode is not building it; it is the window. **Too short** and you lose people with a considered decision. Healthcare decisions in particular are rarely same-session, and a seven-day window on a procedure page throws away most of the people who were genuinely thinking about it. **Too long** and relevance collapses. Somebody who looked at a page five months ago and never came back has moved on, and you are paying to remind them of a decision they made. Sensible starting points, to be adjusted against your own sales cycle: | Intent signal | Window | Why | | ------------------------------ | ------------- | ------------------------------------------ | | Started a form, did not submit | 7 to 14 days | Still in the decision, and recency matters | | Viewed a high-intent page | 30 days | Long enough for a considered choice | | Any site visit | 30 to 90 days | Broad reach, weaker signal | | Repeat visits (three or more) | 60 days | Sustained interest is durable | **Always pair a retargeting audience with the exclusion.** The correct shape is not "viewed the page" but "viewed the page **and** did not convert", which means two event conditions: the intent event with a count at or above 1, and the conversion event with a count of exactly 0. Without the second condition you are retargeting your own customers. *** ## Layering intent with something you know [#layering-intent-with-something-you-know] An event condition tells you what somebody did. A visitor condition tells you who they are. Layering the two is how you turn a broad audience into one worth targeting. Two conditions is usually the sweet spot. Viewed the pricing page **and** is in a state you actually serve. Started an application **and** arrived from paid search rather than from your own email. Visited three times **and** has an email address on file. Past two or three conditions the audience tends to get small enough that platform minimums bite and the estimate stops being reliable. See [Previewing an audience](/docs/audiences/previewing-an-audience). *** ## Lookalike seeds [#lookalike-seeds] Platforms can build a lookalike or similar-audience from a list you provide. The quality of the result is almost entirely determined by the seed. **Seed on your best outcome, not your biggest list.** A seed of everyone who ever converted models an average customer. A seed of people who converted and stayed, or who bought the higher-value thing, models a customer you actually want more of. Smaller and sharper beats larger and diffuse. **Respect the size floor.** A seed needs enough people for the platform to find a pattern. Meta's guidance for a customer list is at least 1,000 people; Google recommends at least 5,000 for a Customer Match list to serve reliably. Below that, tighten less rather than more. **Exclude the seed from the campaign.** This is the step people skip. A lookalike campaign that does not exclude its own seed spends part of its budget re-reaching the customers you built it from, and those customers convert at a higher rate, which makes the lookalike look better than it is. Attach the seed audience as an exclusion on the campaign. **Refresh it.** A seed frozen in a CSV models the customers you had when you uploaded it. Syncing keeps the seed current as your customer base changes. *** ## Suppression beyond advertising [#suppression-beyond-advertising] Not every audience exists to be targeted. Some exist so that somebody is left alone. People who asked not to be contacted, people in an active support escalation, people who already have an appointment this week: each of those is an audience whose only purpose is to be excluded from something. Building them explicitly, and syncing them so they stay current, is cheaper than remembering. *** ## Practices worth adopting [#practices-worth-adopting] **Name for the team, obscure for the platform.** The strategy above is visible in a descriptive audience name, and ad accounts are shared with agencies and contractors. Put the description in **Name** and generate the **Export Name**. See [Export names](/docs/audiences/export-names). **Preview before you sync.** An audience of 40 people will not serve anywhere. Check the estimate and the matchable count first. **Change one thing at a time.** If you widen the window and add a condition in the same edit, a change in performance tells you nothing about which one did it. **Measure what the audience did.** [Audience Performance](/docs/attribution/audience-performance) reports on conversion for audiences, which is the difference between believing an audience works and knowing it. **Retire audiences.** A synced audience runs every night until somebody stops it. Put a recurring review on the calendar. *** ## Next Steps [#next-steps] * **[Building an audience](/docs/audiences/building-an-audience)** for the mechanics of each pattern above. * **[Event conditions](/docs/audiences/event-conditions)** for windows, counts, and the zero-count pattern. * **[Recipes](/docs/audiences/recipes)** for these strategies written out as configurations. * **[Audience Performance](/docs/attribution/audience-performance)** for measuring the result. Need help? Contact [support@oursprivacy.com](mailto:support@oursprivacy.com). Destinations Use this page to sync an Ours Privacy audience to **Vibe**, so you can target the people in that audience with connected-TV campaigns. Ours Privacy rebuilds the audience daily and sends its members to Vibe as hashed email addresses. > **Note:** This is not the same as the **Vibe** destination, which sends individual conversion events to Vibe's server-to-server API. That one measures campaign outcomes. This one builds a targetable audience. You can run both. *** ## Before you start [#before-you-start] * A Vibe account with an advertiser you want the audiences to belong to. * A Vibe API client, created in the Vibe dashboard under API access. Give it both the **Audiences read** and **Audiences write** permissions, or every sync will fail. * An audience in the [Audience Builder](/docs/audiences/building-an-audience) whose members have email addresses. Email is the only identifier this destination matches on, so members without one are skipped. *** ## Add the destination [#add-the-destination] 1. Open [Destinations](https://app.oursprivacy.com/destinations) in Ours Privacy, choose **Add destination**, and pick **Vibe CTV Audiences**. 2. Fill in the settings described below, and turn on **Send hashed email**. Identifiers start switched off, and a destination with none enabled cannot be attached to an audience. 3. Save, then publish a new version. Audience syncs read your **published** settings, so an unpublished destination is skipped. There is no allowed-events step and no event mapping for this destination. It receives audience membership rather than events, so the settings page is the only configuration it has. ### Settings [#settings] * **Client ID** the Client ID of your Vibe API client, from the Vibe dashboard under API access. * **Client Secret** the secret paired with that Client ID. Vibe shows it only once when you create the client. If you no longer have it, generate a new pair in Vibe and update both fields here. * **Advertiser ID** the Vibe advertiser the audiences should belong to, found in the Vibe dashboard. Audiences are created under this advertiser, so pointing at the wrong one puts them somewhere your campaigns cannot target. * **Send hashed email** whether Ours Privacy may send email addresses to this destination, hashed. **This starts switched off, and you have to turn it on and save.** Nothing about a visitor leaves Ours Privacy unless you switch it on here. Hashed email is currently the only identifier Vibe matches on, so while this is off the destination has nothing to match on at all, which is treated as a configuration error rather than an empty audience: you cannot attach an audience to it, and an audience already attached fails its next run with a message saying so, instead of replacing your Vibe audience with one that matches nobody. *** ## Choose which audiences sync [#choose-which-audiences-sync] Selecting audiences happens on the audience, not on the destination. 1. Open the audience in the [Audience Builder](/docs/audiences/building-an-audience). 2. Set an **Export Name**. This is the only name that reaches Vibe, and Vibe displays it in its own interface, so keep it meaningless rather than descriptive. Use **Generate** if you want one picked for you. 3. Read and accept the data-sharing terms shown in the **Sync to Destinations** card. 4. Check your Vibe CTV Audiences destination in that card, then save. Once saved, the audience syncs daily. Each run sends the audience's full current membership, which means: * **Removals happen automatically.** Anyone who no longer matches the audience drops out of Vibe on the next run. * **A missed run fixes itself.** Because every run sends the full membership rather than a change set, the next successful run brings Vibe fully up to date. * **New audiences appear after their first run**, not the moment you attach them. A run is skipped when the destination is **Disabled**, when the audience is not published, or when the destination has not been included in a published version yet. *** ## What Vibe receives [#what-vibe-receives] One field per member: a **SHA-256 hash of their email address**, as lowercase hex with no salt. Plus the audience's Export Name, so you can find the audience in Vibe's interface. That is everything. The raw address is not sent, and no other visitor attribute is: not names, not phone numbers, not addresses. That is not only a description of what we happen to send, it is what the destination is switched on to send. Identifiers are opt-in per destination, and an identifier that is switched off is never even read out of your visitor data when the audience is built. Nothing else can reach Vibe by accident. Vibe matches on the literal lowercased address, so Ours Privacy lowercases and trims each address before hashing and changes nothing else about it. Duplicate people are collapsed to a single record, and members without a usable email address are skipped. Ours Privacy records how many members were delivered against how many were in the audience. ## Match rates [#match-rates] Vibe can only match people it already recognizes in its connected-TV graph, so the audience in Vibe will be smaller than the count in Ours Privacy. **A low or zero match rate does not produce an error on either side.** The sync completes, Vibe reports the audience as active, and it matches fewer viewers than you expected. So when a synced audience underperforms, check the delivered count on the audience in Ours Privacy first: if it is far below the audience total, most members had no email address to match on, and the fix is in your data collection or your audience criteria. Vibe's dashboard is where you confirm what Vibe actually matched. Vibe does not publish a minimum audience size, but a very small audience is unlikely to yield enough matched viewers to run against. *** ## Troubleshooting [#troubleshooting] * **Every sync fails on credentials.** Regenerate the Client ID and Secret in Vibe and paste both into the destination settings. A secret that was rotated in Vibe keeps failing until it is updated here. * **Syncs fail with a permissions error.** Confirm the Vibe API client has both the Audiences read and Audiences write permissions. * **Syncs fail saying the advertiser was not found.** Check the **Advertiser ID** against the Vibe dashboard. * **The sync failed saying no members had a usable email address.** Ours Privacy refuses to send an empty membership, because that would clear the audience in Vibe. Widen the audience criteria or improve email capture, then let the next run try again. * **Nothing has synced at all.** Confirm the destination is Enabled, that you published a version after adding it, and that the audience is published with the destination checked in **Sync to Destinations**. * **Saving the audience, or a sync, failed saying no identifiers are enabled.** **Send hashed email** is off in the destination's settings. It starts off on a new destination, so turn it on, save, and publish a new version. Until then there is nothing for Vibe to match on, so Ours Privacy refuses the run rather than uploading an audience that would match nobody. * **Syncs succeed but Vibe matches almost nobody.** Compare the delivered count against the audience total first, since a gap there means most members had no email address. If the delivered count is healthy and Vibe still reports no matches, contact [support@oursprivacy.com](mailto:support@oursprivacy.com) with the audience and the destination: this is the one failure that neither system reports on its own. * **A sync failed saying another sync is already in progress.** Vibe allows one sync per audience at a time. The next daily run picks it up, so no action is needed unless it repeats. *** ## Next Steps [#next-steps] * **[Audience Destinations](/docs/audiences/audience-destinations)** for how audience syncing works across destinations. * **[Export names](/docs/audiences/export-names)** for the label Vibe sees and how to set it. * **[Published Versions](/docs/version-management)** to publish your destination settings so the sync can use them. Need help? Contact [support@oursprivacy.com](mailto:support@oursprivacy.com). Use this page as the reference for the **Visitor Properties** section of an audience: which attributes you can filter on, what each operator does, and how conditions combine. For behavior rather than attributes, see [Event conditions](/docs/audiences/event-conditions). > **Important:** Advertising platforms are not HIPAA business associates and do not sign BAAs. Read [Compliance for audiences](/docs/audiences/compliance) before sending an audience to any platform. *** ## What you can filter on [#what-you-can-filter-on] The property dropdown is built from your own account, so it reflects what you actually collect. The categories below are always present. ### Consent [#consent] Two properties, and both hold a list of categories rather than a single value, so **contains** is the operator you want. | Property | What it holds | Typical use | | --------------------------- | --------------------------------------------------------------------------------------- | -------------------------------------------------------- | | Accepted Consent Categories | Categories the visitor actively accepted, such as functional, analytics, or advertising | Require affirmative opt-in before advertising to someone | | Rejected Consent Categories | Categories the visitor actively rejected | Exclude a group beyond what a sync already excludes | A visitor with no consent record has neither list populated, which is the case worth thinking about hardest. Nothing filters an audience on consent for you, so both postures are conditions you add here: Rejected Consent Categories **does not contain** `advertising` to exclude recorded rejections, or Accepted Consent Categories **contains** `advertising` if your obligation is affirmative opt-in. The second is stricter, because someone who was never asked is not a rejection. See [Compliance for audiences](/docs/audiences/compliance) and [Cookie Consent](/docs/cookie-consent). Audience Builder Visitor Properties card with Accepted consent categories contains advertising selected. ### Attribution and traffic source [#attribution-and-traffic-source] First-touch and current-session UTM values, referrer, and referring domain. First-touch properties are prefixed with `initial` and are the ones you usually want for an audience, because they describe how the person originally found you rather than how they arrived most recently. Click IDs from ad platforms are also available as properties, which is how you build an audience of people who arrived from a specific platform's paid traffic. ### Identity and profile [#identity-and-profile] Email, phone number, first and last name, date of birth, gender, external ID, company name, and job title, where you collect them. Email is worth singling out. It is the only identifier an audience sync matches on, so a condition requiring email to be not null tells you in Preview how much of your audience is actually deliverable rather than finding out from a delivered count later. See [Audience Destinations](/docs/audiences/audience-destinations). ### Location [#location] City, state, country, and ZIP code, plus latitude, longitude, metro code, and time zone. ### Timing [#timing] First seen and last seen timestamps, which pair with the date operators below for "active since" and "has not been back since" audiences. ### Custom properties [#custom-properties] Anything you send on the visitor. These appear in the dropdown once Ours Privacy has seen them. If a property you send recently is not listed yet, or you need a nested path, an advanced entry mode lets you type the path directly. *** ## Operators [#operators] Every operator below is available on visitor conditions and on the nested conditions inside an event condition. The in-app operator list carries a description of each one; this is the same set. ### Equality and text [#equality-and-text] | Operator | Behavior | | ---------------- | -------------------------------------------------------------------------------------------------------------------------- | | is | Equal to the value. Coerces primitives, so the string `1` matches the number 1. Compares objects and arrays deeply | | is not | The negation of **is** | | contains | The value appears inside a string, or is an element of a list. This is the operator for consent categories | | does not contain | The negation of **contains** | | starts with | A string begins with the value, or a list's first element equals it | | ends with | A string ends with the value, or a list's last element equals it | | is found in | The property appears in a comma-separated list you supply. Handy for a set of countries or campaign names in one condition | | is not found in | The negation of **is found in** | **is** is case-sensitive. For case-insensitive matching, use **contains** for substrings or one of the ignore-case regex operators below. ### Presence [#presence] | Operator | Behavior | | ---------------- | ------------------------------------------------------------ | | is null | The property is null | | is not null | The property exists and is not null | | is undefined | The property was never set | | is not undefined | The property was set, even if to an empty value | | is truthy | Any value that is not false, zero, empty, null, or undefined | | is falsy | False, zero, empty string, null, undefined | | is true | Strictly true, the string `true`, or `1` | | is false | Strictly false, the string `false`, or `0` | The distinction between **is null** and **is undefined** matters when you set a property to an empty value on purpose. If you only want to know whether a value is present at all, **is not null** is usually what you mean. ### Numeric comparison [#numeric-comparison] | Operator | Behavior | | --------------------------- | ------------------ | | is greater than | Numeric comparison | | is greater than or equal to | Numeric comparison | | is less than | Numeric comparison | | is less than or equal to | Numeric comparison | ### Dates [#dates] | Operator | Behavior | | --------------- | -------------------------------------------------------------------------------------------------------------------- | | is before | The date is earlier than the value | | is after | The date is later than the value | | is on or before | Inclusive form of **is before** | | is on or after | Inclusive form of **is after** | | is between | The date falls inside a range, inclusive. Supply two dates separated by a comma, for example `2026-01-01,2026-03-31` | A value that is not a valid date makes the condition false rather than erroring, so a typo in a date shows up as an audience that is smaller than expected. Check Preview. ### Patterns [#patterns] | Operator | Behavior | | ---------------------------------- | ----------------------------------------------------- | | matches regex | The string matches the pattern, case-sensitive | | matches regex (ignore case) | The same, case-insensitive | | does not match regex | The string does not match the pattern, case-sensitive | | does not match regex (ignore case) | The same, case-insensitive | An invalid pattern makes the condition false rather than erroring. Reach for regex when you need one condition to cover several URL shapes; a **contains** condition is easier to read and easier for a colleague to maintain when it will do the job. *** ## Combining conditions [#combining-conditions] Set the connector between conditions to control how they combine. **AND** requires every condition to match, which narrows the audience. Use it for the baseline plus qualifier pattern: an accepted advertising category AND a first-touch UTM medium containing `paid`. **OR** requires any one condition to match, which broadens the audience. Use it for spelling and casing variants of the same underlying thing, such as a UTM medium of `Paid Search` or `paid search` or `cpc`. When you have conditions in both the Visitor Properties and Event Behavior sections, a visitor has to satisfy both sections. Conditions inside each section combine according to that section's own connectors. *** ## Practical notes [#practical-notes] **Start with consent.** For anything that ends up at an advertising platform, put the consent condition in first. It is the condition most likely to be legally load-bearing and the one most easily forgotten once the behavioral logic gets interesting. **Require an enabled identifier when the audience will be synced.** An audience whose members mostly lack a destination-supported identifier syncs successfully and delivers almost nobody. Adding an email or phone is not null condition makes the deliverable size visible in Preview. **Prefer first-touch attribution.** `initial` UTM properties describe how the person found you originally. Current-session values describe the most recent visit, which for a returning visitor is often direct traffic and tells you nothing about acquisition. **Widen carefully.** Each OR you add makes the audience bigger in ways that are hard to predict from reading the conditions. Preview after each change rather than after five. *** ## Next Steps [#next-steps] * **[Event conditions](/docs/audiences/event-conditions)** to filter on behavior as well as attributes. * **[Previewing an audience](/docs/audiences/previewing-an-audience)** to check what your conditions actually match. * **[Recipes](/docs/audiences/recipes)** for worked configurations that combine both condition types. * **[Cookie Consent](/docs/cookie-consent)** for how consent categories are collected in the first place. Need help? Contact [support@oursprivacy.com](mailto:support@oursprivacy.com). Ours Privacy CMP includes **auditor-grade receipts** so your team can produce clear evidence for audits, legal reviews, and internal compliance checks. ## What You Can Show [#what-you-can-show] With consent reporting, you can document: * **Who** made a consent choice * **When** it happened * **What** they chose * **Where** it happened (site/page and location context) * **Which consent policy context** applied at that time ## Why This Matters [#why-this-matters] Audits and legal reviews usually require more than a dashboard screenshot. They require evidence that is: * clear and understandable to non-technical reviewers * tied to real visitor decisions * exportable for compliance workflows * traceable to the policy active at the time of consent ## Auditor-Grade Receipts [#auditor-grade-receipts] Ours Privacy CMP gives you auditor-grade receipts that combine consent actions with policy context so you can confidently answer questions like: * "Did this person provide consent?" * "What exactly did they consent to?" * "Which policy was in effect when they made that choice?" ## Consent Audit Export (Subject Lookup) [#consent-audit-export-subject-lookup] Use **Compliance → Subject Export** to review privacy-safe aggregate lookup evidence before you export compliance data. See [Subject Export](/docs/subject-export) for the full walkthrough. The Subject Export page showing privacy-safe aggregate lookup evidence for a selected consent setting and date range, including summary counts for matching consent activity before export. 1. Open **Compliance → Subject Export**. 2. Under **Scope of search**, pick the consent setting and a date range. 3. Under **Find the subject**, choose one identifier type and enter the value: * Email * IP address * Visitor ID 4. Run **Search** to confirm whether evidence exists. 5. Under **Pick what to include**, choose how much history to export: * **Consent receipts**: cookie banner opt-ins, opt-outs, and dismissals only * **Consent + activity**: adds the subject's full event history for the matched visitor IDs * **Consent, events, dispatches**: also adds destination dispatch records 6. Run the export to download CSV evidence. The lookup returns a found/not-found status plus matched event and visitor counts so compliance teams can confirm scope before export. ## CSV Evidence Fields [#csv-evidence-fields] The audit CSV includes core evidence and policy context, including: * visitor id, event, action, page, timestamp, email * visitor region, country, visitor matching region, IP, user agent * consent setting id and consent id * selected rule kind and rule primary region * published version id and published version number * accepted and rejected categories * GPC, GPC status, and is GPC modal visible ## Recommended Workflow [#recommended-workflow] 1. Use **Compliance → Subject Export** to locate a subject by email, IP, or visitor ID. 2. Confirm lookup status and event counts. 3. Run a full export for the selected subject and date range. 4. Attach the export to your audit or legal ticket. 5. Store the evidence package according to your retention policy. ## Best Practices [#best-practices] * Limit access to consent exports to authorized compliance and legal users. * Use consistent date ranges and naming conventions for audit packages. * Archive exported evidence in your approved compliance storage location. * Review and validate your consent configuration regularly. ## Next Steps [#next-steps] * **[Data Sharing Report](/docs/compliance-report)**: View a full summary of your data governance rules, destination configurations, and data mappings * **[Consent Event Tracking](/docs/cookie-consent/consent-tracking)**: Understand what is captured * **[General Settings](/docs/cookie-consent/general-settings)**: Configure consent behavior and versioning * **[Regional Policies](/docs/cookie-consent/regional-policies)**: Align policy behavior by jurisdiction # Browser Support [#browser-support] Ours Privacy's Cookie Consent Management Platform (CMP) is designed for broad compatibility across modern browsers and devices. We officially test and support the following environments: * **Chrome** (latest and previous major version) * **Firefox** (latest and previous major version) * **Edge** (latest and previous major version) * **Safari (desktop)** (latest and previous major version) * **Safari (iOS)** (latest and previous major version) * **iOS browsers** (latest and previous major version) * **Android browsers** (latest and previous major version) This includes support for Windows, macOS (including Sonoma and Sequoia), iOS, and Android operating systems. > **Note:** While we officially test the current and previous major versions of each browser, our platform is engineered for maximum compatibility and may work on a wider range of versions and environments. For the best experience and compliance, we recommend using up-to-date browsers. *** ## Next Steps [#next-steps] * **[Installation](/docs/cookie-consent/installation)**: Get started with the CMP * **[FAQs](/docs/cookie-consent/faqs)**: Common questions and answers Ours Privacy CMP automatically tracks consent activity in your Ours Privacy account. This gives your team an aggregate view of consent behavior over time and supports compliance workflows with evidence you can export. For the definitions of banner views, opt-ins, opt-outs, dismissals, and no action in the dashboard, see [Consent Analytics](/docs/consent-analytics#how-outcomes-are-counted). The Consent Analytics trend chart showing daily banner views, explicit opt-ins, explicit opt-outs, and close icon clicks across the selected period. ## What Tracking Supports [#what-tracking-supports] Consent tracking helps you: * monitor consent trends over time * understand how visitors interact with your consent experience * investigate specific consent decisions when needed * generate **auditor-grade receipts** for compliance reviews ## What Is Included [#what-is-included] Consent tracking captures the context needed for reporting and audits, including: * consent decisions and updates * timing of user actions * visitor-level linkage for investigation * location and policy context for compliance review Common fields include: * `consent_id`: stable consent identifier used for audit linkage * `consent_setting_id`: CMP consent setting (widget/config) id * `published_version_id` and `published_version_number`: published configuration version at event time * `selected_rule_kind` and `selected_rule_label`: regional/policy rule selected at event time * region and country context ## Configuration Requirements [#configuration-requirements] To enable consent tracking: 1. Set a valid **Web SDK Token** in CMP settings. 2. Publish your CMP configuration. 3. Ensure the CMP script loads before non-essential trackers. ## Next Steps [#next-steps] * **[Auditing and Reporting](/docs/cookie-consent/auditing-and-reporting)**: Generate compliance-ready exports * **[General Settings](/docs/cookie-consent/general-settings)**: Configure consent and policy behavior ### Do I need to use the `window.ours_consent` methods? [#do-i-need-to-use-the-windowours_consent-methods] For most users, you do **not** need to use these methods directly. The consent UI and banner handle all standard consent flows for you. These APIs are intended for advanced or custom integration scenarios only. *** ### How do I add a link to the Consent Preferences Center from my privacy policy or footer? [#how-do-i-add-a-link-to-the-consent-preferences-center-from-my-privacy-policy-or-footer] You can use the JavaScript SDK to open the preferences modal when a user clicks a link. Add an anchor tag with an `onclick` handler: ```html Manage Cookie Preferences ``` This is commonly used in privacy policies, footers, or anywhere you want to give users quick access to update their consent choices. Visitor preference center modal with cookie categories and controls for saving consent choices. *** ### Is the CMP compliant with GDPR, CCPA, and HIPAA? [#is-the-cmp-compliant-with-gdpr-ccpa-and-hipaa] Yes, Ours Privacy CMP is designed to help you comply with GDPR, CCPA, HIPAA, and other major privacy regulations. You can configure region-specific rules and consent modes to meet legal requirements. *** ### Can I customize the look and feel of the consent banner? [#can-i-customize-the-look-and-feel-of-the-consent-banner] Absolutely! You can fully customize the text, button labels, and even translations for different regions to match your brand and compliance needs. *** ### How does script blocking work? [#how-does-script-blocking-work] The CMP automatically blocks scripts and network requests for services that require consent. You can also manually tag scripts for advanced blocking control. Scripts are only enabled after the user grants consent for the relevant category. *** ### What is Enforce mode? [#what-is-enforce-mode] Enforce mode blocks all resources from domains not listed in your configured Services, in addition to standard category-based blocking. It's a per-rule setting, so you can enable it for specific regions (e.g., EU visitors) while keeping Monitor mode for others. See the [Script Blocking](/docs/cookie-consent/script-blocking#blocking-modes-monitor-vs-enforce) guide for details. *** ### Will Enforce mode break my site? [#will-enforce-mode-break-my-site] Enforce mode blocks any third-party resource you haven't categorized in your Services list. If your service list is incomplete, legitimate integrations may be blocked. We recommend validating your configuration in Monitor mode first and using the Web Scanner to discover uncategorized resources before enabling Enforce mode. *** ### Can I use my own domain for the CMP script? [#can-i-use-my-own-domain-for-the-cmp-script] Yes, you can configure a custom domain to serve the CMP script, ensuring first-party trust and compliance. *** ### How do I test if my implementation is working? [#how-do-i-test-if-my-implementation-is-working] After installing the CMP, load your site and verify the banner appears. Test accepting, rejecting, and managing preferences. You can also use browser developer tools to check that scripts are blocked or enabled based on consent. *** ### Does the CMP support IAB TCF (Transparency and Consent Framework) or GPP (Global Privacy Platform)? [#does-the-cmp-support-iab-tcf-transparency-and-consent-framework-or-gpp-global-privacy-platform] No, Ours Privacy CMP does not currently support IAB TCF v2.2 or the IAB Global Privacy Platform (GPP) standard. If your implementation requires IAB TCF or GPP compliance, this CMP may not meet those needs. *** ### Does the CMP support Global Privacy Control (GPC)? [#does-the-cmp-support-global-privacy-control-gpc] Yes, Ours Privacy CMP automatically detects and honors the GPC signal sent by browsers. If a user has GPC enabled, the CMP allows you to configure how each individual category you have behaves. This helps you comply with CCPA, CPRA, and similar privacy laws. *** ### When does the CMP renew or reset cookie consent? [#when-does-the-cmp-renew-or-reset-cookie-consent] Changing consent settings alone does **not** renew or reset consent. The CMP will only reset a visitor's stored consent when either: * **The consent cookie name is changed** (e.g., `op_consent` is changed to `op_consent2`) * **The consent revision number is bumped**: The revision number is a field in your [Default Consent Settings](/docs/cookie-consent/general-settings#default-consent-settings) that you control. You can change it at any time, and doing so will invalidate all previously stored consent, prompting every visitor to consent again on their next visit. This is typically used when your legal or compliance team requires fresh consent, for example, after adding new cookie categories, onboarding a new advertising vendor, or making significant changes to your privacy policy. Bump the revision number whenever the scope of what visitors are consenting to has materially changed. * **The visitor clears their browser cookies**: When a visitor clears their cookies, the stored consent cookie is removed and they will be prompted to consent again on their next visit. This is standard browser behavior, not something you control. If none of the above occur, consent remains unchanged for 12 months (unless the cookie expires). Updating other consent settings, such as category names, banner text, or regional policies, will not trigger a re-prompt on its own. *** ### Removing cookies on consent withdrawal [#removing-cookies-on-consent-withdrawal] When users withdraw consent, you may want to remove cookies that were set based on their previous consent choices. Modern browsers have security restrictions that limit cookie deletion capabilities, especially for third-party cookies and HttpOnly cookies. You can only delete cookies set by your domain due to Same-Origin Policy restrictions. For an example implementation showing how to delete cookies if you need to implement something like this, see this [GitHub Gist Guide](https://gist.github.com/tylerzey/36b95766213a65782496e4b7bcbae1ea). *** ### Is the CMP making third-party network requests? [#is-the-cmp-making-third-party-network-requests] To block or allow cookies based on consent, the CMP has to watch every other script on your page. Because it's watching everything, browser developer tools will sometimes list the CMP as part of the chain when a third-party script makes a network request. This does **not** mean the CMP is calling that domain; it means the CMP was monitoring the call when it happened. The actual request is coming from whatever third-party tool (analytics, ads, etc.) is installed on your site. If you are tightening your Content Security Policy (CSP) and see unfamiliar domains appearing to originate from the CMP, allow those domains based on the actual third-party services your site uses, not because the CMP is calling them. *** ### Does the CMP affect search engine crawling and SEO? [#does-the-cmp-affect-search-engine-crawling-and-seo] The CMP detects search engine crawlers (bots) and fully removes itself from the page for those visitors. When a crawler is detected: * The consent banner is not rendered * No scripts are blocked or modified * The page content is delivered to the crawler in full, without consent-based restrictions This means search engines can crawl and index your full site content unimpeded. The "hide from bots" setting (enabled by default) only suppresses the visual banner for crawlers, and does not restrict what content they can access. This is intentional SEO-friendly behavior. *** ## Next Steps [#next-steps] * **[Installation](/docs/cookie-consent/installation)**: Get started with the CMP * **[General Settings](/docs/cookie-consent/general-settings)**: Configure your CMP settings # General Settings [#general-settings] Your **General Settings** section is the central place to configure everything about how your CMP works, looks, and enforces consent. It includes: * **Categories**: Define the types of cookies and trackers you need consent for, like "Necessary," "Analytics," or "Advertising." * **Vendors & Trackers**: Maintain a list of known vendors and domains that need to be blocked or managed, with category assignments. * **Consent Modal & UI Text**: Customize all text, labels, translations, and button layout behavior shown to visitors in your consent banner and preferences modal. * **Default Consent Settings**: Set the default consent mode (opt-in or opt-out), regional overrides, automatic page refreshing, and versioning. Each of these helps you: * **Collect clear, granular consent** for each purpose and vendor. * **Ensure compliance** with laws like GDPR, CCPA, and HIPAA. * **Provide a branded, clear experience** with customizable text and design. * **Keep your site privacy-friendly** by preventing unauthorized tracking before consent. Below you'll find details on each part: *** ## Categories [#categories] Define the categories users see when managing their consent. Examples include: * **Necessary** (cannot be disabled) * **Analytics** * **Advertising** * **Custom categories** you define Categories allow granular consent collection and make sure your site aligns with legal requirements for purpose-based consent. The Categories card listing four consent categories — Necessary, Functional, Analytics, and Marketing — each with its label, slug, and ordering controls. *** ## Vendors & Trackers [#vendors--trackers] Set up the list of scripts, domains, and vendors that need consent management: * Add domain patterns (e.g. `google-analytics.com`) * Assign them to categories * Add labels for user-facing vendor names (e.g. "Google Analytics") * Add internal notes for team management When the **Show Vendors in Preferences** setting is enabled (see [Default Consent Settings](#default-consent-settings) below), vendor labels are displayed under their respective categories in the preferences modal. This gives visitors transparency into which specific services are associated with each consent category. This ensures accurate blocking and transparent disclosure. The Vendors & Trackers card, where each row pairs a domain pattern with the consent category it belongs to and the user-facing vendor label shown in the preferences modal. *** ## Consent Modal & UI Text [#consent-modal--ui-text] Customize the full user experience: * Banner titles and descriptions * Buttons (Accept All, Reject All, Preferences) * Included button layout strategy per region * Terms of Service and Privacy Policy URLs * Footer text and preferences modal sections * Support for translations and region-specific language Helps create a clear, branded, and compliant interface for your visitors. ### Included Buttons (Consent Modal) [#included-buttons-consent-modal] Ours Privacy CMP supports 5 consent modal button layout presets: * **Accept, Reject and Preferences** * **Accept and Preferences** * **Information Only (No Buttons)** * **Preferences Only** * **Accept Only** This gives you granular control over how action-heavy or action-light your modal should be by jurisdiction and policy model. The Modal UI Options card in the Design tab, where the Included Buttons setting selects which combination of Accept, Reject, and Preferences buttons the consent modal shows. *** ## Default Consent Settings [#default-consent-settings] Set the overall behavior of your consent system: * Consent mode (opt-in or opt-out) * Auto show banner on load * Auto Show Dismiss Settings * Disable page interaction until consent * Show Vendors in Preferences * Region-specific overrides with tailored modes and text * Consent revision/versioning to ensure you can roll out new policies safely These settings ensure your site behaves correctly by default for all users, while giving flexibility for local laws and best practices. The Default Consent Settings card showing the defaults that apply when no regional override matches — Resource Blocking set to Monitor, Auto Show Modal and Hide from Bots enabled, Lock Page Interaction disabled, Show Vendors in Preferences enabled, a default language of English, and Auto Dismiss set to Never (always show). ### Consent Revision [#consent-revision] The consent revision number lets you invalidate all previously stored consent and require visitors to consent again. Bump this number when the scope of what visitors are consenting to has materially changed — for example, after adding new cookie categories or making significant updates to your privacy policy. For more details on all the scenarios that trigger re-consent, see the [FAQ: When does the CMP renew or reset cookie consent?](/docs/cookie-consent/faqs#when-does-the-cmp-renew-or-reset-cookie-consent). ### Show Vendors in Preferences [#show-vendors-in-preferences] When enabled, vendor labels are displayed under their respective categories in the preferences modal. For example, if you have a vendor labeled "Google Analytics" assigned to the "Analytics" category, users will see "Google Analytics" listed under "Analytics cookies" when they open their consent preferences. * **Disabled** (default): Vendor labels are not shown in the preferences modal. Only category names are visible. * **Enabled**: Vendor labels appear under each category, giving visitors full transparency into which services are being used. This setting can be configured independently per region using [Regional Policies](/docs/cookie-consent/regional-policies). For example, you might enable vendor display for EU visitors (where GDPR requires detailed disclosure) while keeping it disabled for other regions. ### Auto Show Dismiss Settings [#auto-show-dismiss-settings] When "Auto show banner on load" is enabled, you can configure when the consent modal automatically dismisses: * **Dismiss Mode**: Choose when the modal should automatically dismiss: * **Never**: The modal continues to show on every page until the user interacts with it (default behavior) * **After X Pages**: Automatically dismisses after the user navigates through a specified number of pages * **After X Seconds**: Automatically dismisses after a specified number of seconds * **Page Count** (when "After X Pages" is selected): The number of pages the user can navigate to before the modal automatically dismisses. The modal will show on each page until this count is reached. * **Seconds** (when "After X Seconds" is selected): The number of seconds the modal should be displayed before automatically dismissing. The timer starts when the modal is first shown. **Use Cases**: * **Never**: Best for strict compliance requirements where explicit user interaction is required * **After X Pages**: Useful for reducing banner fatigue while still ensuring visibility across multiple pages * **After X Seconds**: Ideal for providing a brief opportunity for users to see and interact with the banner before it auto-dismisses *** ## Global Privacy Control (GPC) Notification [#global-privacy-control-gpc-notification] When a user has **Global Privacy Control (GPC)** enabled in their browser and your CMP settings are configured to respect GPC signals, a notification will appear in the consent window stating: "We detected and are honoring your Global Privacy Control (GPC) signal". This notification is visually highlighted to inform users that their GPC decision is being respected. GPC respect settings can be configured globally or per region using [Regional Policies](/docs/cookie-consent/regional-policies), allowing you to comply with privacy laws like CCPA and CPRA that require honoring GPC signals. *** ## Next Steps [#next-steps] * **[Regional Policies](/docs/cookie-consent/regional-policies)**: Create region-specific consent policies * **[Script Blocking](/docs/cookie-consent/script-blocking)**: Configure automatic and manual script blocking * **[Styling & Customization](/docs/cookie-consent/styling-and-customization)**: Customize the visual appearance # Global Privacy Control (GPC) [#global-privacy-control-gpc] Global Privacy Control (GPC) is a browser signal that communicates a visitor's wish to opt out of the sale or sharing of their personal information. Several US privacy laws (such as CCPA/CPRA in California and similar laws in other states) recognize GPC as a legally meaningful opt-out signal. The Ours Privacy CMP can detect GPC and automatically reject the categories you choose on the visitor's behalf. > This page explains how to configure the CMP. It is general guidance, not legal advice. Which categories should respect GPC, and in which regions, depends on your product, your data practices, and the advice of your own legal or privacy counsel. *** ## What the CMP Does When It Detects GPC [#what-the-cmp-does-when-it-detects-gpc] When a visitor arrives with GPC turned on in their browser and your CMP is configured to respect it: * The categories you have marked as GPC-respecting are moved to the rejected set before the visitor interacts with anything. * **The consent banner does not open.** The visitor has already told you what they want, so there is nothing left to ask. In its place the CMP shows a small acknowledgement reading **"We detected and are honoring your Global Privacy Control (GPC) signal"**, so the visitor can see their signal was recognized. * Scripts in the rejected categories are blocked by [Script Blocking](/docs/cookie-consent/script-blocking) the same as any other rejection. This is what that visitor sees instead of the usual banner: A clinic web page with no consent banner. In the bottom-left corner a small white pill with a green dot and green text reads: We detected and are honoring your Global Privacy Control (GPC) signal. The acknowledgement asks for nothing and blocks nothing. Visitors without GPC on the same page still get the full banner and still choose for themselves. For this to work, two settings need to line up. Both are described below. *** ## Step 1: Mark the Categories That Should Respect GPC [#step-1-mark-the-categories-that-should-respect-gpc] Open your consent setting's **Default Consent Settings** section and find the **Consent Posture** card. Each category listed there has an **Auto Disable on GPC** toggle — open a category to set it, and categories that have it on are marked with an **Auto disable on GPC** badge in the list. Turn it on for every category you want GPC to automatically reject. Commonly this includes: * **Advertising** * **Analytics** (if your analytics use constitutes a "sale" or "share" under applicable law) * **Marketing** It typically does not include **Necessary** or other categories that do not involve the sale or sharing of personal information. The Consent Posture card with consent mode set to must explicitly opt-in, listing four categories and their default consent state. Analytics and Marketing each carry an Auto disable on GPC badge under Category Behavior, while Necessary is read-only and Functional has no GPC badge. > **Important:** Only categories with this toggle enabled are rejected by GPC. A category without it will remain in its default state even for visitors who have GPC turned on. *** ## Step 2: Use a Regional Policy That Includes Those Categories [#step-2-use-a-regional-policy-that-includes-those-categories] GPC handling is evaluated against the rule the visitor lands in — your default configuration or a [Regional Policy](/docs/cookie-consent/regional-policies) override. For visitors from regions where GPC is legally recognized (for example California), make sure the active rule: * Is scoped to the relevant regions (e.g., `US-CA`, and consider adding `US-UNKNOWN` per the [regional policies guidance](/docs/cookie-consent/regional-policies#handling-unknown-us-regions-us-unknown)). * Includes the categories you marked as GPC-respecting in Step 1. The Associated Regions card on a regional rule, listing the four regions the rule applies to — California (US-CA), Unknown State (US-UNKNOWN), Colorado (US-CO), and Virginia (US-VA) — above an Edit Regions button. If a regional rule does not include any GPC-respecting categories, the CMP has nothing to reject on the visitor's behalf. Visitors hitting that rule see the normal consent banner instead of the acknowledgement, even with GPC turned on. *** ## Testing Your Configuration [#testing-your-configuration] 1. Install a browser extension that enables GPC (for example, Privacy Badger or DuckDuckGo Privacy Essentials), or use a browser that sends GPC natively with the setting turned on. 2. Load a page on your site that is scoped to the regional policy you configured. 3. Confirm the GPC acknowledgement appears and that the consent banner does **not** open. 4. Open `window.ours_consent.getConsent()` in the browser console and verify the GPC-respecting categories are listed under `rejectedCategories`. 5. Confirm that scripts in those categories are not executing (for example, check the Network tab for the vendor domains you expect to be blocked). For an audit-grade record, export the visitor's consent from [Auditing and Reporting](/docs/cookie-consent/auditing-and-reporting). *** ## FAQ [#faq] ### Do I also need to configure anything for server-side tracking? [#do-i-also-need-to-configure-anything-for-server-side-tracking] Yes, if you use the Ours Privacy CDP or send events to destinations from the server. The CMP setting described on this page only governs what happens in the visitor's browser. Events that your backend sends after the browser has stored consent are evaluated separately. Use [Global Data Governance](/docs/global-data-governance) to create rules that stop server-side dispatch when the relevant consent category has been rejected. This is a separate configuration from the CMP-level toggle and is typically required alongside it. ### Does turning on auto-disable prove we are compliant with CCPA, CPRA, or other laws? [#does-turning-on-auto-disable-prove-we-are-compliant-with-ccpa-cpra-or-other-laws] No. Honoring GPC is one piece of how several US privacy laws define a valid opt-out, but compliance depends on many other factors specific to your business — your data practices, contracts with vendors, privacy notices, response workflows, and more. Please work with your legal or privacy counsel to determine what your obligations are and whether this configuration is sufficient. ### Why is the GPC acknowledgement not appearing for a test visitor? [#why-is-the-gpc-acknowledgement-not-appearing-for-a-test-visitor] Typical reasons: * No category in the active regional policy has **Auto Disable on GPC** enabled. * The visitor is being matched to a different regional rule than expected. Check the rule's regions, including whether `US-UNKNOWN` is handled. * The GPC extension is not actually sending the signal on your page (some extensions only send GPC on specific contexts). Verify with `navigator.globalPrivacyControl === true` in the browser console. ### What happens to a returning visitor who had already accepted a category before GPC was turned on? [#what-happens-to-a-returning-visitor-who-had-already-accepted-a-category-before-gpc-was-turned-on] On the next load, the CMP re-evaluates consent against the current GPC state. Categories marked as GPC-respecting are moved to the rejected set, overriding the earlier acceptance, and the acknowledgement is shown. ### Can I configure GPC handling differently per region? [#can-i-configure-gpc-handling-differently-per-region] Yes. Because GPC handling is evaluated against the regional policy the visitor hits, you can include or omit GPC-respecting categories from each regional rule independently. For example, you might configure a US-CA rule that respects GPC for advertising and analytics, while an EU rule relies on explicit opt-in consent instead. *** ## Next Steps [#next-steps] * **[General Settings](/docs/cookie-consent/general-settings)**: Configure categories and the per-category GPC toggle * **[Regional Policies](/docs/cookie-consent/regional-policies)**: Scope your GPC-respecting rules to the right regions * **[Auditing and Reporting](/docs/cookie-consent/auditing-and-reporting)**: Export visitor-level evidence that GPC was honored If you are using the Ours Privacy CDP, consent is already managed server-side and you typically do not need to set up Google Consent Mode separately. If your setup requires Google Consent Mode, authenticated customers can use the in-app CMP JavaScript SDK reference to listen for consent events and pipe them into Google Consent Mode. Below is a minimal example: ```html ``` Then, when the user consents via the Ours Privacy CMP, update Google Consent Mode: Visitor preference center with controls for necessary, analytics, and advertising consent choices. ```javascript // On user acceptance gtag('consent', 'update', { ad_storage: 'granted', analytics_storage: 'granted', }); ``` *** ## Next Steps [#next-steps] * **[Script Blocking](/docs/cookie-consent/script-blocking)**: Learn about automatic script blocking * **[General Settings](/docs/cookie-consent/general-settings)**: Configure categories and vendors Ours Privacy CMP is a HIPAA-ready cookie banner and consent management platform. It is built for teams that need both strong consent controls and clear compliance evidence. *** ## Choose the visitor experience [#choose-the-visitor-experience] Choose a consent experience that fits your site's interaction model, policy requirements, and brand. Configure it in the Design tab, then preview the exact banner before you publish. *** ## Why Teams Choose Ours Privacy CMP [#why-teams-choose-ours-privacy-cmp] * **HIPAA-ready consent management** for regulated environments * **Auditor-grade receipts** for compliance and legal workflows * **Consent analytics and reporting** tied to real visitor behavior * **Region-specific consent policies** for GDPR, CCPA, and global requirements * **Automatic and manual script blocking** to prevent non-consented tracking * **Versioned configuration and policy history** for controlled change management * **Custom domains and flexible UI controls** for trust and brand consistency *** ## Key Features [#key-features] The Ours Privacy CMP provides a complete consent management solution: * **[Installation & Quick Start](/docs/cookie-consent/installation)**: Get up and running with a simple script tag * **[Styling & Customization](/docs/cookie-consent/styling-and-customization)**: Customize themes, colors, typography, layouts, and button behavior * **[General Settings](/docs/cookie-consent/general-settings)**: Configure categories, vendors, UI text, and consent defaults * **[Regional Policies](/docs/cookie-consent/regional-policies)**: Create region-specific policies for GDPR, CCPA, and other regulations * **[Script Blocking](/docs/cookie-consent/script-blocking)**: Automatic and manual script blocking before consent * **[Consent Tracking](/docs/cookie-consent/consent-tracking)**: Monitor consent activity in your Ours Privacy account * **[Auditing and Reporting](/docs/cookie-consent/auditing-and-reporting)**: Generate auditor-grade receipts and export evidence * **[Google Consent Mode](/docs/cookie-consent/google-consent-mode)**: Guidance for Google integrations *** ## Getting Started [#getting-started] 1. **[Install the CMP](/docs/cookie-consent/installation)**: Add a single script tag to your website's `` 2. **Configure your settings**: Set categories, vendors, regional policies, and defaults 3. **Customize the experience**: Match your brand and legal requirements 4. **Publish and test**: Validate banner behavior, blocking, and tracking 5. **Enable compliance workflows**: Use auditor-grade receipts and exportable reporting The Consent Settings list showing seven separate consent configurations for a clinic: its main site, patient portal, Spanish microsite, fertility centre, campaign landing pages, careers site and blog. Each has a created date above a search box and an Add Consent Settings button. *** ## Documentation [#documentation] * **[Installation](/docs/cookie-consent/installation)**: Step-by-step installation guide * **[Styling & Customization](/docs/cookie-consent/styling-and-customization)**: Complete customization options * **[General Settings](/docs/cookie-consent/general-settings)**: Configure categories, vendors, and consent defaults * **[Regional Policies](/docs/cookie-consent/regional-policies)**: Set up region-specific consent rules * **[Script Blocking](/docs/cookie-consent/script-blocking)**: Automatic and manual blocking configuration * **[Consent Tracking](/docs/cookie-consent/consent-tracking)**: Consent activity tracking * **[Auditing and Reporting](/docs/cookie-consent/auditing-and-reporting)**: Auditor-grade receipts and evidence exports * **[Google Consent Mode](/docs/cookie-consent/google-consent-mode)**: Google Consent Mode integration guidance * **[Browser Support](/docs/cookie-consent/browser-support)**: Supported browsers and environments * **[FAQs](/docs/cookie-consent/faqs)**: Common questions and answers *** ## Accessibility [#accessibility] The Ours Privacy CMP is built to meet modern accessibility standards so your consent banner is usable by every visitor. The banner and preference controls are keyboard navigable and screen reader compatible, conforming to **WCAG 2.2 Level AA** and **Section 508**. *** ## Need Help? [#need-help] If you have questions about the Cookie Consent Management Platform or need assistance with setup, reach out to [support@oursprivacy.com](mailto:support@oursprivacy.com). # Installing the Cookie Consent Management Platform [#installing-the-cookie-consent-management-platform] Setting up your CMP is fast and easy. Just follow these steps: ## Step 1: Copy Your Install Script [#step-1-copy-your-install-script] In your configuration under **Install & Setup**, you'll see an installation script tag like: ```html ``` The Install and Setup panel's Quick Install tab, showing the Installation Script block with an optional pre-styled banner stylesheet link and the required consent script tag pointing at a first-party CDN with the account's token, alongside a Copy button. The panel also offers an optional pre-styled stylesheet `` you can include if you want the default banner styling. ## Step 2: Paste It Into Your Website's `` [#step-2-paste-it-into-your-websites-head] Add the script tag as high as possible in your site's ``. This ensures it runs before other tracking scripts and can manage consent blocking correctly. ## Step 3: Publish Your Configuration [#step-3-publish-your-configuration] Make sure you've saved and published your CMP configuration in the dashboard. ## Step 4: Verify the Banner [#step-4-verify-the-banner] Load your site and confirm that the consent banner/modal displays correctly. Test acceptance, rejection, and preference management to ensure it meets your requirements. > **Important:** Place the script before any other analytics or advertising tags so it can block them if the user hasn't consented. > **Note:** If you have a [custom domain](/docs/custom-domains) configured for your Ours Privacy account, you can load the Ours Privacy consent management platform from your own first-party custom domain as well. *** ## Next Steps [#next-steps] * **[Styling & Customization](/docs/cookie-consent/styling-and-customization)**: Customize the look and feel of your consent banner * **[General Settings](/docs/cookie-consent/general-settings)**: Configure categories, vendors, and consent modes * **[Script Blocking](/docs/cookie-consent/script-blocking)**: Set up automatic and manual script blocking # Consent JavaScript SDK [#consent-javascript-sdk] Use this page to find the `window.ours_consent` JavaScript SDK reference — methods, events, examples, and the consent settings REST API details. The full reference lives inside the authenticated Ours Privacy app, where it stays in sync with your account's consent configuration. Consent Settings Open a consent settings configuration and select **API Reference** for SDK methods, events, examples, and consent settings REST API details. The window.ours_consent section of the in-app API Reference. Each method gets its own panel with the value it returns: getConsent() returns a ConsentState, documented with the four possible consent action types and a code example, above a collapsed section covering the initial consent state and category defaults. *** ## Next Steps [#next-steps] * [Installation](/docs/cookie-consent/installation) * [Script Blocking](/docs/cookie-consent/script-blocking) * [Regional Policies](/docs/cookie-consent/regional-policies) * [Google Consent Mode](/docs/cookie-consent/google-consent-mode) React frameworks behave differently from static sites because the framework hydrates server-rendered HTML on the client. If a third-party script inserts visible UI into the page before hydration finishes, React may detect a mismatch and replace that part of the DOM. For the Ours Privacy CMP, that means React and Next.js integrations should balance two concerns: * **Banner stability** in hydrated applications * **Consent blocking** for scripts and resources that may load before the CMP initializes This page outlines the current recommended patterns. Example repos: * [with-ours/ours-nextjs-example](https://github.com/with-ours/ours-nextjs-example) for Next.js * [with-ours/ours-vite-react-router](https://github.com/with-ours/ours-vite-react-router) for React with Vite and React Router *** ## Recommended Pattern for Next.js [#recommended-pattern-for-nextjs] In Next.js applications, load the CMP with `next/script` using `strategy="afterInteractive"`. ```tsx import Script from 'next/script'; export default function Layout({ children }) { return ( <> ``` With this pattern: * The browser does **not** execute the script immediately * The CMP can later enable it after consent is granted * You avoid relying on the CMP to win a timing race against the framework For more detail, see **[Script Blocking](/docs/cookie-consent/script-blocking)**. *** ## React SPA Pattern [#react-spa-pattern] If you are using a client-only React application (for example, a React SPA without server rendering), you can often use the standard CMP installation pattern in the page shell or HTML template. Even in SPAs, the same principle applies: * If a script is present in the initial HTML and must remain blocked before consent, manually block it * If a third-party tool injects scripts before the CMP is available, the CMP cannot retroactively prevent that first execution *** ## Tag Managers and Other Early Loaders [#tag-managers-and-other-early-loaders] If you use GTM or another tag manager, do not assume `afterInteractive` CMP loading will block anything the tag manager fires before CMP initialization. For strict control: * Delay tag manager execution until consent is available, or * Use manual blocking for scripts and resources present in the initial page HTML, and * Ensure your service list is complete so the CMP can classify allowed and blocked resources correctly *** ## Programmatic UI Control [#programmatic-ui-control] If you need the application to control banner visibility, use the JavaScript SDK after the CMP has loaded: ```javascript window.ours_consent.show(); window.ours_consent.showPreferences(); window.ours_consent.hide(); ``` Visitor preference center opened by the CMP, with analytics and advertising choice controls and a Save my choices button. Authenticated customers can find the full JavaScript SDK API in the consent settings **API Reference** section of the Ours Privacy app. *** ## Summary [#summary] For React and Next.js applications, the current recommended approach is: * Load the CMP using a framework-safe client-side pattern such as `afterInteractive` * Use manual blocking for anything present in the initial HTML that must remain inert until consent is known * Do not allow third-party loaders to execute before the CMP if you need strict first-load blocking This gives you a reliable banner experience in hydrated frameworks while preserving consent controls for resources you explicitly mark up. *** ## Next Steps [#next-steps] * **[Installation](/docs/cookie-consent/installation)**: Standard CMP installation guidance * **[Script Blocking](/docs/cookie-consent/script-blocking)**: Automatic and manual blocking details * **[Script Conflicts](/docs/cookie-consent/script-conflicts)**: Conflicts with DOM and script-timing manipulation Ours Privacy handles an unexpected third-party script in two layers that work together. The CMP enforces in the moment, and the Web Scanner reports across scans. * **Real-time blocking** happens in the visitor's browser. An uncategorized script is stopped before it executes, on the first page view it appears on. * **Scan reporting** happens on your scanner's regular schedule. That is when a host you have not categorized, or one that is new or newly high-risk, shows up in your results and triggers a notification. In short: an uncategorized script is **blocked immediately**, and **reported at the next scan**. Enforcement does not wait for a scan, and reporting gives you the history to act on. *** ## Where unexpected scripts come from [#where-unexpected-scripts-come-from] Most uncategorized scripts are not an attack. They are ordinary drift in how a site gets built, and they usually arrive one of three ways: * Someone adds a vendor through a tag manager without telling the team that maintains your consent config. * An approved vendor loads another vendor at runtime, so a script you never chose appears alongside one you did. * A vendor changes what its own script does, so code you already classified starts behaving differently. The common thread is timing rather than intent. None of these wait for your next review cycle, which is why the blocking layer does not either. *** ## How real-time blocking works [#how-real-time-blocking-works] Real-time blocking is enforced by the Ours Privacy consent script running on your pages. Because it loads early and wraps the browser APIs that fetch resources, it makes an allow-or-block decision at the moment something tries to load rather than after the fact. Two things determine the decision: 1. **Whether the resource matches a service you have configured**, and whether the visitor has consented to that service's category. 2. **Your resource blocking mode**, which decides what happens to resources that match nothing you have configured. In **Monitor** mode, an uncategorized resource is allowed. In **Enforce** mode, an uncategorized third-party resource is blocked. Enforce mode is the setting that holds back a script nobody has classified yet. Put another way: in Enforce mode your configured services act as an allowlist. A third-party resource that is not on it does not run. Resources served from your own domain and its subdomains are always allowed, in either mode. The Resource Blocking selector that chooses between the two modes, shown set to Monitor, with help text noting that Monitor allows uncategorized resources through while Enforce blocks them until they are categorized. For the steps to configure services, categories, and the blocking mode, see [Script Blocking](/docs/cookie-consent/script-blocking). ### What the blocking layer covers [#what-the-blocking-layer-covers] Enforce mode applies to resources in the page when it loads and to resources injected later: * **Scripts**, including ones written into the page after load and ones created at runtime by other scripts. * **Images**, including tracking pixels created at runtime. * **Iframes** and **stylesheet or preload links**. * **Network requests** made with `fetch`, `XMLHttpRequest`, or `navigator.sendBeacon`. That last group is what covers the case where a script is already on the page and starts sending data somewhere new. The requests it makes to an unclassified destination are subject to the same decision. > **Note:** Blocking is best effort by design. A script that a browser has already begun fetching may appear in your browser's network panel even though Ours Privacy prevents it from executing. Load the consent script as early as possible in your HTML so decisions are made before other code runs. *** ## Where blocking shows up, and where reporting does [#where-blocking-shows-up-and-where-reporting-does] Blocking and reporting are deliberately separate, because they serve different readers. **Blocking is a per-visitor decision.** It happens in browsers you never see, and it is visible in the browser console while you test. It is enforcement, not a record. **Reporting is the record.** The scanner crawls your site on its schedule and notifies your team about what needs attention, including hosts you have not categorized. A host is reported as uncovered when it is new since your last scan and matches neither your configured consent services nor a suppression rule. Those arrive alongside newly high-risk and newly escalated hosts in the same findings notification. See [How scanning works](/docs/web-scanner/how-it-works). So you do get told about uncategorized scripts, on the scan cycle. What you do not get is one alert per block, because a single uncategorized script would otherwise notify you on every page view. The scan aggregates them into one reviewable list instead. *** ## Using the two layers together [#using-the-two-layers-together] The scanner and the blocking layer answer different questions, and each covers the other's limitation. | | Real-time blocking | Web Scanner | | --------------------- | ------------------------------------------- | ------------------------------------------------------ | | **When it acts** | On page load, per visitor | On each scheduled scan | | **What it does** | Stops the resource from executing | Inventories what loaded and flags risk | | **Where you see it** | Browser console while testing | Scan results, email, and in-app notifications | | **What it tells you** | Nothing on its own, it just enforces | Which hosts are new, uncategorized, or newly high-risk | | **Best at** | Keeping an unclassified script from running | Telling you what exists and what to classify | A practical way to run both: 1. Start in **Monitor** mode and let the scanner build your picture of what actually loads on your site. 2. Work through the findings and classify each real vendor into a consent category. See [Recommended fixes](/docs/web-scanner/remediation). 3. Once your service list covers your legitimate integrations, switch the rule to **Enforce** so anything new is blocked on arrival. 4. Keep reading scan results. Enforce mode holds back the uncategorized, and the scanner is still how you learn something new appeared and decide whether it belongs. > **Important:** Turning on Enforce mode before your service list is complete will block integrations you have not classified yet. Validate in Monitor mode first, and use your scan results to confirm coverage. *** ## Next Steps [#next-steps] * [Script Blocking](/docs/cookie-consent/script-blocking): configure services, categories, and Monitor or Enforce mode. * [Regional Policies](/docs/cookie-consent/regional-policies): run Enforce in one region while another stays on Monitor. * [How scanning works](/docs/web-scanner/how-it-works): the scan schedule and change notifications. * [What the scanner detects](/docs/web-scanner/detections): third-party scripts, cookies, CSP gaps, and accessibility checks. Questions about blocking behavior on your site? Reach out to [support@oursprivacy.com](mailto:support@oursprivacy.com). # Creating Regional Specific Consent Policies [#creating-regional-specific-consent-policies] The Ours Privacy CMP supports **Regional-Specific Overrides** to help you comply with GDPR, CCPA, and other state or country-specific privacy laws. These overrides allow you to redefine any consent settings, UI text, categories, or behavior for visitors from specific regions. You can think of them as **complete reconfigurations for specific regions**. For example: * Change the **consent mode** to *opt-in* for EU/EEA visitors and *opt-out* for US states that allow it. * Customize the **consent banner text** to match legal requirements in different jurisdictions. * Provide **translations** for specific languages or legal disclaimers. * Override **categories** or default states for specific laws. * Tailor the **preferences modal** for different compliance frameworks. * Override **Auto Show Dismiss Settings** for specific regions (e.g., auto-dismiss after 3 pages for EU visitors, never auto-dismiss for California visitors). * Set the **[Blocking Mode](/docs/cookie-consent/script-blocking#blocking-modes-monitor-vs-enforce)** independently per region (e.g., Enforce mode for EU visitors, Monitor mode for US visitors). *** ## How It Works [#how-it-works] * Define as many region-specific rules as needed in your configuration. * Select the region or country code: * Country code: `US`, `CA`, `DE`, etc. (ISO 3166-1 alpha-2) * Multi-country region: `EU` * US state: `US-CA` (California), `US-TX` (Texas), etc. * Canadian province or territory: `CA-QC` (Quebec), `CA-ON` (Ontario), etc. * Customize all available settings (categories, vendors, UI text, consent mode, etc.) just like your global/default configuration. * Users in those regions will see the specifically tailored banner and experience you've designed. > **Note on Canadian provinces:** Quebec's Law 25 typically requires consent and disclosure obligations distinct from the rest of Canada and from PIPEDA. Use a `CA-QC` rule to deliver a Quebec-specific banner experience while keeping a separate `CA` rule for the rest of the country. This flexibility ensures that your site: * Automatically adapts to visitors' locations. * Meets global privacy law requirements. * Offers a clear, localized, and compliant experience. > **Tip:** Always review legal requirements in target regions to ensure your overrides meet local consent standards. The Region-Specific Overrides card listing three rules, each showing the regions it covers, its consent mode, whether the modal auto-shows, and how many categories it defines: an opt-in rule for the European Union, the United Kingdom, and Switzerland; an opt-out rule for California, Colorado, Virginia, and unknown US states; and an opt-in rule for Quebec. *** ## Handling Unknown US Regions (US-UNKNOWN) [#handling-unknown-us-regions-us-unknown] In some cases, our geolocation service cannot determine the specific US state for a visitor. This can happen when: * The visitor is using a **VPN** or proxy service * The visitor is behind a **corporate network** with shared egress IPs * The **geo-IP database** lacks precise data for certain IP ranges For these visitors, the region is set to `US-UNKNOWN` instead of a specific state code like `US-CA` or `US-NY`. ### Best Practice: Add US-UNKNOWN to Your Most Conservative Rule [#best-practice-add-us-unknown-to-your-most-conservative-rule] If you have state-specific rules (e.g., `US-CA` for California's CCPA requirements), we recommend adding `US-UNKNOWN` to the **Additional Regions** field of your most privacy-protective rule. **Example:** If your California (`US-CA`) rule has the strictest opt-in requirements, edit that rule and add `US-UNKNOWN` to its Additional Regions. This ensures visitors with indeterminate locations receive the same compliant treatment as California visitors. This way, you're never accidentally under-protecting a visitor who might be in a regulated state but whose specific location couldn't be determined. > **Note:** `US-UNKNOWN` only applies to US traffic. Non-US countries without region data will fall back to country-level rules or your default configuration. *** ## Next Steps [#next-steps] * **[General Settings](/docs/cookie-consent/general-settings)**: Configure your default global settings * **[Styling & Customization](/docs/cookie-consent/styling-and-customization)**: Customize region-specific text and translations # Script Blocking [#script-blocking] Our CMP is designed to **prevent tracking scripts from running until consent is given**. It does this in two complementary ways: **automatic blocking** (always on) and **manual blocking** (optional for advanced control). All blocking relies on the concept of **Services** you define in your configuration. Each Service includes: * A **domain pattern** to match requests (e.g. `*.google-analytics.com`) * The **category** it belongs to (like Analytics or Advertising) When a user hasn't consented to a category, any Service matching that category will be blocked — provided the category's **"enabled by default"** setting is off. Categories configured as "enabled by default" are active before the visitor takes action. To block a category before consent, set its "enabled by default" to off. *** ## Automatic Blocking [#automatic-blocking] Automatic blocking is always enabled. It scans your pages for network requests and script loads that match any configured Service domains: * Blocks requests that match configured Services immediately on page load. * Also blocks dynamically injected scripts (e.g. from tag managers). * Stops these scripts from executing until consent is granted for their category. **Important:** Always test your implementation to ensure no critical functionality is inadvertently blocked. **Important:** Scripts that are present on the page during load (not injected via tag managers) may have their assets loaded in the browser's resources tab. However, Ours will still attempt to block these scripts from executing, assuming you've properly configured your services and loaded the Ours Privacy CMP script early enough in your HTML page. **Important:** Always configure your web scanner and check it frequently. This will help you identify which pixels, scripts, and cookies are being set without proper categorization. If a script needs to be loaded on the page (not injected), it's best practice to include it directly in your HTML with the `data-category` and `type="text/plain"` attributes shown in the manual blocking section below. *** ## Blocking Modes: Monitor vs Enforce [#blocking-modes-monitor-vs-enforce] Your CMP operates in one of two blocking modes, configured **per rule** (so each region can use a different mode): ### Monitor Mode (Default) [#monitor-mode-default] In Monitor mode, the CMP only blocks resources that match a **configured Service** with a category the user hasn't consented to. Resources from domains not listed in your Services are allowed to load normally. This is the default for all rules. Use Monitor mode while you're setting up your CMP, building out your service list, and validating your configuration. The Resource Blocking selector set to Monitor, with the help text explaining that Monitor allows uncategorized resources through while Enforce blocks them until they are categorized. ### Enforce Mode [#enforce-mode] In Enforce mode, the CMP **blocks all resources from domains not listed in your Services** in addition to the standard category-based blocking. Any script, image, iframe, link, or network request from an uncategorized third-party domain is blocked automatically. Resources from your own site's domain (and its subdomains) are always allowed, even in Enforce mode. **When to enable Enforce mode:** * Your service list is complete and covers all legitimate third-party integrations on your site * You've validated your configuration in Monitor mode and confirmed nothing critical is missing * You want the strictest possible blocking posture for compliance (e.g., GDPR, HIPAA) **How to enable it:** 1. Navigate to your consent setting's rule configuration (default or a regional override) 2. Find the **Resource Blocking** selector 3. Switch from **Monitor** to **Enforce** A European Union (EU) Consent Settings rule with Resource Blocking switched to Enforce, alongside the rule's other per-region settings — Auto Show Modal, Lock Page Interaction, Hide from Bots, Show Vendors in Preferences, Default Language, and Auto Dismiss. > **Important:** Enabling Enforce mode without a comprehensive service list will block third-party integrations you haven't categorized yet. Always validate in Monitor mode first. Use your [Web Scanner](/docs/cookie-consent/general-settings) to discover uncategorized resources before switching. > **Tip:** You can run Enforce mode for EU visitors while keeping Monitor mode for US visitors by configuring each [regional rule](/docs/cookie-consent/regional-policies) independently. Enforce mode is also what holds back a script nobody has classified yet. For how that blocking relates to what the Web Scanner reports, and when your team is notified, see [Real-time script blocking](/docs/cookie-consent/real-time-blocking). *** ## Manual Blocking [#manual-blocking] Manual blocking gives you precise, in-page control over which scripts are held back until consent. **Use manual blocking for any script that exists in your HTML document when the page loads.** This includes: * Scripts in your HTML source code * Scripts added during server-side rendering * Scripts that are part of your initial page structure For this approach, you **manually mark scripts in your HTML** with special attributes that identify their category: ```html ``` When the user consents to "analytics," these scripts are dynamically enabled. **What manual blocking controls:** * **Execution**: Scripts marked with `type="text/plain"` won't execute until consent * **Download**: Scripts still download initially (unless you add additional attributes) * **Timing**: Script execution is delayed until the user grants consent **When you don't need manual blocking:** * Scripts dynamically inserted via tag managers (e.g. Ours Privacy Tag Manager) * Scripts added by JavaScript after page load **Benefits of manual blocking:** * Full control over *which* inline or external scripts are gated * Ensures even scripts without network patterns can be held until consent * Useful for self-hosted or custom third-party scripts The **Manual Scripts** tab of your Install & Setup panel shows the same reference in-app, including the exact category keys your configuration accepts: The Manual Scripts tab of the Install and Setup panel, explaining how to change a script tag to type text/plain and add consent attributes, with a Google Analytics example, the meanings of data-category and data-service, and the four category keys this configuration accepts: necessary, functional, analytics, and marketing. > **Tip:** Combine automatic blocking (for domain-level detection) with manual blocking (for page-specific script tags) to ensure comprehensive coverage. *** ## Next Steps [#next-steps] * **[General Settings](/docs/cookie-consent/general-settings)**: Configure Services and categories for blocking * **[Installation](/docs/cookie-consent/installation)**: Ensure proper script placement for blocking to work # Script Conflicts [#script-conflicts] The Ours Privacy CMP works by manipulating the DOM (the collection of elements that make up a webpage) to detect, block, and control script execution based on user consent. When other scripts—such as lazy loading libraries or tools like Cloudflare Rocket Loader—also manipulate the DOM or script execution, **we cannot guarantee that the CMP will be able to manage and block scripts correctly**. Any script that manipulates the DOM or alters script execution timing can potentially interfere with the CMP. This includes optimization tools, caching plugins, and other third-party scripts that modify how or when scripts load and execute. *** ## Cloudflare Rocket Loader [#cloudflare-rocket-loader] [Rocket Loader](https://support.cloudflare.com/hc/en-us/articles/200168056-What-does-Rocket-Loader-do-) is a Cloudflare product that loads JavaScript asynchronously to optimize page loading times. When Rocket Loader is enabled, **we cannot guarantee that the CMP will be able to manage and block scripts correctly**, because its asynchronous loading conflicts with the CMP's ability to detect and control which page elements load and execute according to consent. ### Recommended Solution [#recommended-solution] If you use Rocket Loader, we recommend **manual mode** to improve the chance that the CMP can control which page elements are loaded and executed. Even with manual mode, we cannot guarantee correct behavior. Only use Rocket Loader to optimize elements that you are certain do not set any cookies or only set necessary cookies. ### Configuration Steps [#configuration-steps] 1. In your Cloudflare dashboard, navigate to **Performance Settings** 2. Set the **Rocket Loader** option to **Manual** 3. If needed, manually mark up the elements that you wish to be loaded by Rocket Loader: ```html ``` > **Important:** Scripts marked with `data-cfasync="true"` will be able to set cookies regardless of the visitor's consent choices. Only mark up elements that do not set any cookies or only set necessary cookies. *** ## Lazy loading libraries [#lazy-loading-libraries] Lazy loading libraries (such as lazysizes) and the CMP both manage `src` and `data-src` on images and iframes. The CMP uses these attributes to block or restore resources based on consent; lazy loaders use them to defer loading until the element is in view. Because both systems read and write the same attributes, **we cannot guarantee that the CMP will be able to manage and block scripts correctly** when a lazy loading library is used. If you use lazy loading for images or embeds that require consent, test carefully—conflicts may prevent correct blocking or restoration. ### Skip Blocking Classes [#skip-blocking-classes] To stop the two systems fighting over the same element, add your lazy loader's class name to **Skip Blocking Classes** in your consent setting's **General** section. The CMP leaves elements carrying those classes alone entirely. The Skip Blocking Classes card with a warning that elements carrying these classes will not be blocked by the consent system, an input for adding a class name, and two configured skip classes: lazyload and rocket-loader-ignore. That exemption is the whole point of the setting, and also its risk: an element you skip is no longer governed by consent at all, so you are responsible for making sure it respects the visitor's choices some other way. Only add classes for elements that set no cookies, or only necessary ones. *** ## Other Common Conflicts [#other-common-conflicts] Other optimization and caching tools that may cause similar conflicts include: * **WP Rocket** (WordPress caching plugin) * **LiteSpeed Cache** (WordPress optimization tool) * **Other script optimization plugins** that defer, delay, or asynchronously load scripts * **Any custom scripts** that manipulate script loading or execution timing The same principles apply: when these or similar tools are used, **we cannot guarantee that the CMP will be able to manage and block scripts correctly**. *** ## General Recommendations [#general-recommendations] ### Identify Potential Conflicts [#identify-potential-conflicts] * Review all scripts, plugins, and optimization tools on your site * Look for tools that: * Defer or delay script loading * Load scripts asynchronously * Modify script execution timing * Manipulate the DOM to inject or modify scripts ### Configuration Best Practices [#configuration-best-practices] * **Exclude CMP scripts from optimization**: Ensure the Ours Privacy CMP script is excluded from any optimization, minification, or caching processes * **Test thoroughly**: After configuring optimization settings, test your website to ensure: * The consent banner displays correctly * Scripts are properly blocked before consent * Scripts are enabled after consent is granted * User preferences are respected ### When in Doubt [#when-in-doubt] If you're experiencing issues with script blocking or consent management: 1. Temporarily disable optimization tools to see if the issue resolves 2. Check browser developer tools to verify scripts are being blocked/enabled correctly 3. Review your optimization tool settings to ensure CMP scripts are excluded 4. Contact [support@oursprivacy.com](mailto:support@oursprivacy.com) if you need assistance *** ## Next Steps [#next-steps] * **[Script Blocking](/docs/cookie-consent/script-blocking)**: Learn about automatic and manual script blocking * **[Installation](/docs/cookie-consent/installation)**: Ensure proper script placement for blocking to work * **[General Settings](/docs/cookie-consent/general-settings)**: Configure Services and categories for blocking Ours Privacy CMP offers extensive customization options to match your website's branding and user experience. You can control everything from colors and fonts to layout and button styles, ensuring your consent banner feels like a natural part of your site. *** ## Visual Customization Options [#visual-customization-options] You can configure styles directly in the application via the **Design** tab in your CMP configuration. The Design tab covers core visual customization needs, including colors, button styles, and border radius. You can adjust these settings and use the **Preview** button to see how your changes will look before they go live. **Important:** Changes must be published to take effect. They are not applied immediately. All of these customization options are available through point-and-click controls in the Design tab, no coding required: * **Theme Selection**: Choose from multiple pre-built themes including light, dark, and minimal designs * **Color Customization**: Set primary colors, background colors, text colors, and accent colors using color pickers * **Typography**: Control font families, sizes, and weights for all text elements * **Layout Options**: Choose between banner, modal, or floating button layouts * **Button Styling**: Customize button shapes, sizes, colors, and hover effects with simple controls * **Border & Shadow**: Add borders, rounded corners, and shadow effects * **Responsive Design**: All themes automatically adapt to mobile and desktop screens *** ## How different two banners can actually be [#how-different-two-banners-can-actually-be] Every banner below is the same product on the same page. Each one is a different configuration: a different layout and screen position, a different number of action buttons, different button wording, and a different amount of copy. Nothing here required custom code. Each is a set of choices in the Design tab and the text fields described above. Copy length matters more than most teams expect. The same layout looks unrecognizable with one line of text versus five, so treat your description as a design decision and not only a legal one. *** ## Advanced Customization with CSS Variables [#advanced-customization-with-css-variables] The Design tab covers most use cases. If you're not technical, you can typically configure everything you need without editing CSS. For technical users who require advanced customization beyond the options available in the Design tab, CSS variables and CSS classes are available. You can find a complete reference of available CSS variables in the **CSS Variables Reference** tab within the Design section of your CMP configuration. These are intended for engineering and design teams who need deeper control over the consent modal's appearance. The CSS Variables Reference tab of the Theme Styling card, listing every variable you can override grouped into Colors, Layout and Spacing, and Other Properties. Each entry names the part of the modal it controls, such as --cc-btn-primary-bg for the primary button background. ### How far the variables go [#how-far-the-variables-go] This gallery is the mirror image of the one earlier on this page. There, the configuration changed with every slide; here it is held completely still. Each banner below is the same consent configuration on the same page, and only the CSS variable values differ. Every value is listed in the reference above. Nothing about the banner's markup, copy, or button order changed between them. Because the consent banner renders into your page rather than into an iframe, your own stylesheet can set these variables. Declare them on `:root` in a stylesheet that loads **after** the consent snippet. The CMP sets its own defaults on `:root` too, so the last declaration wins. *** ## Text & Content Customization [#text--content-customization] Beyond visual styling, you have complete control over all text content: * **Banner Headlines**: Customize the main title and description text * **Button Labels**: Set custom text for "Accept All," "Reject All," "Preferences," and other buttons * **Category Descriptions**: Write clear explanations for each cookie category * **Legal Text**: Customize privacy policy links and legal disclaimers * **Regional Translations**: Provide different text for different geographic regions * **Accessibility**: Ensure all text meets accessibility standards *** ## Try Before You Configure [#try-before-you-configure] Want to see how different customization options look before implementing them on your site? The **Design** tab in your CMP configuration provides an in-app interface for configuring and previewing styles. You can adjust colors, button styles, and other visual settings, then use the **Preview** button to see how your changes will appear before publishing them to your live site. * **Demo different themes** and see how they look in real-time * **Test color combinations** and typography options * **Preview layouts** on different screen sizes * **Experiment with text content** and translations * **Compare different consent modes** (opt-in vs opt-out) * **Test regional variations** and compliance scenarios * **Validate different button-layout strategies** for each jurisdiction before publishing The Preview Consent Modals dialog. Selectors choose which region rule and viewport size to preview, buttons show the consent modal or the preferences modal or reset the preview, and a mock web page below renders the live consent banner with the configured colors, copy, and button labels. The preview functionality lets you experiment with all customization options without affecting your live site, making it easy to find the perfect configuration for your brand and compliance needs. *** ## Example: Consent Platform Theme [#example-consent-platform-theme] Ours Privacy CMP offers a variety of theme options to match your website's branding and user experience needs. *** ## Next Steps [#next-steps] * **[General Settings](/docs/cookie-consent/general-settings)**: Configure categories, vendors, and UI text * **[Regional Policies](/docs/cookie-consent/regional-policies)**: Set up region-specific text and translations A content experiment shows different versions of a page to different visitors, then measures which version converts better. Each variant is defined as a list of **DOM modifications**: typed actions that update the rendered page (set text, swap an image, toggle styles, inject custom CSS or JS, and so on). The runtime applies them to the assigned variant so the visitor sees only their version. You stay on the same URL. Half your visitors see your original headline. The other half see a new one. The version that drives more sign-ups, demo requests, or purchases wins. In reporting, both groups count as experiment participants. Visitors assigned to the original experience are the control group, and visitors assigned to changed experiences are treatment groups. Both control and treatment receive experiment impression events; visitors outside traffic allocation do not. This is the most common type of experiment. Use it when you want to test a change to a page without building a whole new page. *** ## What You Can Test [#what-you-can-test] Anything visible on the page is fair game: * **Headlines and body copy**: does "Start your free trial" outperform "Get started today"? * **Button text and color**: does a green button convert better than a gray one? * **Hero images**: which photo drives more engagement? * **Entire sections**: test a short-form hero against a long-form one * **Calls to action**: price anchoring, urgency copy, social proof placement * **Layout changes**: reorder sections, show or hide elements, restructure a form *** ## Available DOM Modification Actions [#available-dom-modification-actions] Every variant is a list of these actions. AI assistants and the REST API use this canonical action set: | Action | What it does | `value` shape | | -------------- | ------------------------------------------------- | ------------------------------------------ | | `setText` | Replace the element's text content | Plain string | | `setHtml` | Replace the element's inner HTML | HTML string | | `setStyle` | Set one or more inline CSS properties | JSON-stringified `{ property: value }` map | | `setAttribute` | Set one or more attributes (e.g. `class`, `href`) | JSON-stringified `{ name: value }` map | | `setImage` | Update an `` `src` (or background image) | URL string | | `remove` | Remove the element from the DOM | (none) | | `insertBefore` | Insert HTML immediately before the element | HTML string | | `insertAfter` | Insert HTML immediately after the element | HTML string | | `customCss` | Inject a `
Content to exclude
``` *** ## Parent-Child Inheritance [#parent-child-inheritance] The `data-translate-skip` attribute cascades to all child elements: ```html

Title

Paragraph

  • Item 1
  • Item 2
``` *** ## Selective Inclusion (Not Supported) [#selective-inclusion-not-supported] Currently, there's no way to include a child element if a parent has `data-translate-skip`. Plan your exclusions at the most specific level needed: ```html

This won't work

Excluded text

This will be translated

``` *** ## Dynamic Content [#dynamic-content] The `data-translate-skip` attribute works for dynamically-added content too. Any new elements with this attribute will be automatically excluded. ```javascript // Dynamically added content with exclusion const el = document.createElement('div'); el.setAttribute('data-translate-skip', ''); el.textContent = 'This will not be translated'; document.body.appendChild(el); ``` *** ## Best Practices [#best-practices] 1. **Be specific**: Apply exclusions to the smallest element necessary 2. **Brand consistency**: Exclude brand names, product names, and trademarks 3. **Legal content**: Consider excluding legal text that must remain in original language 4. **Technical terms**: Exclude industry-specific terms that shouldn't be translated 5. **Test thoroughly**: Verify exclusions work as expected in all languages *** ## Next Steps [#next-steps] * [Protect brand names and terms](/docs/translate/no-translate-terms) everywhere they appear * [View supported languages](/docs/translate/supported-languages) * [Common questions](/docs/translate/faqs) # Frequently Asked Questions [#frequently-asked-questions] Common questions about the Translation Widget. *** ## General Questions [#general-questions] ### Does the widget auto-translate based on browser language? [#does-the-widget-auto-translate-based-on-browser-language] **Yes.** The widget can automatically translate based on the visitor's browser language settings. Additionally, if a visitor has previously selected a language, that preference is restored automatically on their next visit. ### Where is the language preference stored? [#where-is-the-language-preference-stored] The visitor's language choice is stored in browser **localStorage** under the key `translate-widget-language`. It persists until the visitor clears their browser storage or clicks "Reset translations" in the widget. ### Can visitors reset to the original language? [#can-visitors-reset-to-the-original-language] **Yes.** The widget includes a reset option that clears the language preference and reloads the page to restore original content. ### Can I see how the widget is being used? [#can-i-see-how-the-widget-is-being-used] **Yes.** Each widget has a built-in **Analytics** tab showing pages translated, unique visitors, and demand broken down by language, site, and page. See [Usage Analytics](/docs/translate/analytics). *** ## Content & Translation [#content--translation] ### What content gets translated? [#what-content-gets-translated] The widget translates all visible text content on the page, including headings, paragraphs, button text, links, and table content. It automatically skips form inputs, hidden elements, scripts, and styles. ### How do I exclude specific content from translation? [#how-do-i-exclude-specific-content-from-translation] Add the `data-translate-skip` attribute to any element: ```html Brand Name ``` See [Excluding Content](/docs/translate/excluding-content) for more details. ### Can I block specific words from ever being translated? [#can-i-block-specific-words-from-ever-being-translated] **Yes.** Add them to the **Never Translate Terms** list on your widget in the Ours Privacy dashboard. The widget preserves those terms in their original form everywhere they appear, in every supported language, with no markup changes required. This is the right approach for brand names, drug names, and other terms you want to keep consistent across all languages. See [No-Translate Terms](/docs/translate/no-translate-terms) for details. ### Does it work with dynamically-loaded content? [#does-it-work-with-dynamically-loaded-content] **Yes.** The widget automatically detects new content added to the page. This works with: * Single Page Applications (SPAs) * Infinite scroll * AJAX-loaded content * JavaScript-rendered content New content is automatically translated when detected. *** ## Customization [#customization] ### Can I change the widget's position? [#can-i-change-the-widgets-position] **Yes.** Choose from four positions in your widget configuration: * `bottom-right` (default) * `bottom-left` * `top-right` * `top-left` ### Can I customize the colors? [#can-i-customize-the-colors] **Yes.** You can set: * **Theme**: Light or dark mode * **Brand color**: Any hex color for accents ### Can I limit which languages are available? [#can-i-limit-which-languages-are-available] **Yes.** In the Ours Privacy dashboard, select only the languages you want to offer. Visitors will only see your selected languages in the widget. The Languages Offered multi-select dropdown with a search box, Select all and Deselect all controls, and a checklist of languages including English, Spanish, French, and Chinese (Simplified) checked as enabled *** ## Technical Questions [#technical-questions] ### Why doesn't the widget appear on my site? [#why-doesnt-the-widget-appear-on-my-site] Common causes: 1. **Domain not allowed**: Add your domain to the widget's allowlist in the Ours Privacy dashboard 2. **Wrong widget ID**: Verify the ID in your script tag matches your widget 3. **Script blocked**: Check if ad blockers or security tools are blocking the script 4. **JavaScript errors**: Check browser console for errors ### What happens if the translation API is slow or fails? [#what-happens-if-the-translation-api-is-slow-or-fails] The widget handles errors gracefully: * **Automatic retries**: Failed requests retry automatically * **Error UI**: Shows a retry button if translation fails * **Content preservation**: Errors don't break already-translated content * **Original content safe**: Your original content is never modified ### Does the widget affect page performance? [#does-the-widget-affect-page-performance] The widget is designed for minimal impact: * **Async loading**: Script loads asynchronously, doesn't block page render * **Debounced updates**: DOM changes are batched for efficiency * **Efficient caching**: Reduces API calls for repeated content * **Lazy initialization**: Only activates when visitor interacts *** ## Privacy & Security [#privacy--security] ### Is the widget designed for HIPAA compliance? [#is-the-widget-designed-for-hipaa-compliance] **Yes.** The Translation Widget is designed to support HIPAA compliance requirements. All translation operations flow through Ours Privacy infrastructure, and only visible text content is transmitted, never form data, passwords, or sensitive inputs. ### What data is sent for translation? [#what-data-is-sent-for-translation] Only visible text content on the page. The widget explicitly excludes: * Form inputs and textareas * Hidden content * Scripts and styles * Password fields ### Does it use Google Translate? [#does-it-use-google-translate] **No.** Unlike browser-based Google Translate, our widget uses Ours Privacy's own translation infrastructure. This means: * No third-party tracking * Data handling designed to support HIPAA compliance * Your visitors' browsing data stays private *** ## Troubleshooting [#troubleshooting] ### The widget appears but shows no languages [#the-widget-appears-but-shows-no-languages] Check that you've enabled languages in your widget configuration in the Ours Privacy dashboard under **Translations**. ### Some content isn't being translated [#some-content-isnt-being-translated] The content may be: * Hidden (`display: none` or `visibility: hidden`) * Inside a form input * Marked with `data-translate-skip` * Inside an iframe * Inside a ` ``` The **Widget Preview** card on your widget's Settings tab shows this exact snippet, ready to copy: The Widget Preview card on a translation widget's Settings tab, with a note that the widget preview appears in the lower corner, a read-only textarea containing the embed script tag with the widget's CDN URL and id, and a Copy Embed Code button *** ## Step 3: Add to Your Website [#step-3-add-to-your-website] Add the script tag to your website, ideally just before the closing `` tag: ```html ``` *** ## Framework-Specific Installation [#framework-specific-installation] ### Next.js [#nextjs] Add the script to your root layout or use the `Script` component: ```tsx import Script from 'next/script'; export default function RootLayout({ children }) { return ( {children} ``` ### WordPress [#wordpress] Add to your theme's `footer.php` or use a plugin to inject scripts in the footer. ### Shopify [#shopify] Add to your theme's `theme.liquid` file before the closing `` tag. *** ## Domain Allowlist [#domain-allowlist] For security, the widget only works on domains you've added to your allowlist. Make sure to add all domains where you'll use the widget: * `yoursite.com` * `www.yoursite.com` * `staging.yoursite.com` (if testing on staging) You can manage allowed domains in the Ours Privacy dashboard under **Translations**. *** ## Verify Installation [#verify-installation] After adding the script: 1. Visit your website 2. Look for the floating translate button (default: bottom-right corner) 3. Click the button and select a language 4. Verify that page content translates *** ## Troubleshooting [#troubleshooting] ### Widget Not Appearing [#widget-not-appearing] * **Check the allowlist**: Ensure your domain is on the allowlist in widget settings * **Check for JavaScript errors**: Open browser console for any errors * **Verify script URL**: Ensure the widget ID is correct ### Widget Loads But No Languages [#widget-loads-but-no-languages] * **Check widget configuration**: Ensure you've enabled languages in the widget settings *** ## Next Steps [#next-steps] * [Configure appearance](/docs/translate/configuration) to match your brand * [Protect brand names and terms](/docs/translate/no-translate-terms) from being translated * [Exclude specific content](/docs/translate/excluding-content) from translation # No-Translate Terms [#no-translate-terms] Translations Use this page to keep specific words and phrases in their original form, in every language the widget offers. This is the right tool for brand names, product names, drug names, legal entities, and other terms that must read identically across all languages. > **Already using `data-translate-skip`?** That attribute is the right choice when you want to exclude a single HTML element — a logo lockup, a footer block, a code snippet. No-translate terms are the right choice when the same word appears in many places and you want every occurrence preserved without touching the markup. *** ## Configure in the dashboard [#configure-in-the-dashboard] 1. Open your translation widget. 2. In **Never Translate Terms**, add one term per line. 3. Click **Save Changes**. The Never Translate Terms card with one term per line, listing a clinic's brand name, its care and portal product names, two provider names, its legal entity name, and two drug names that must stay untranslated The widget will pick up the new list on the next page load. There is no need to update the embed snippet. *** ## How it works [#how-it-works] 1. Add the terms to the **Never Translate Terms** list on your widget. 2. The widget script picks up the updated list automatically on the next page load. 3. When a visitor selects a language, the widget protects each occurrence of those terms — case-insensitively — before sending text to be translated. 4. The translated content is rendered with your terms restored to the casing you configured. The same term is protected everywhere it appears on the page, including content added later by JavaScript. *** ## Behavior [#behavior] * **Case-insensitive matching.** `Acme`, `ACME`, and `acme` all match the configured term and are restored to the casing you supplied in the dashboard. * **Longest match wins.** If you list both `Acme` and `Acme Healthcare`, the longer term takes precedence wherever both could match. * **Substring-safe by configuration, not by default.** `Acme` will match inside `AcmeCorp`. If you do not want substring matches, configure the longer, more specific term instead (e.g. add `AcmeCorp` to the list as well). * **Dynamic content.** Terms are protected in content added after page load (SPAs, infinite scroll, AJAX inserts). * **Form inputs.** The widget does not translate form inputs or textareas; you do not need to add their contents to this list. * **Limits.** Up to 500 terms per widget, each up to 200 characters. *** ## Examples [#examples] ### Brand names [#brand-names] Add `Acme Healthcare` and `AcmeCare` to the **Never Translate Terms** list. Result: every occurrence stays in English, even when the surrounding sentence is translated to Spanish, French, or any other supported language. ### Drug and product names [#drug-and-product-names] Add `OncoMed XR`, `Curevia`, and `Restoril`. Drug and product names should stay identical across languages so patients and clinicians can match the term to packaging and prescriptions. ### Legal and trademark text [#legal-and-trademark-text] Add `Acme Holdings, Inc.` to keep the legal entity name intact in every language. Combine with [`data-translate-skip`](/docs/translate/excluding-content#legal-text) on standalone legal blocks for full coverage. *** ## Per-page override (escape hatch) [#per-page-override-escape-hatch] For one-off pages — a staging URL, a draft brand name not yet in the dashboard — you can add extra terms from the page itself by setting `window.OURS_NO_TRANSLATE_TERMS` **before** the widget script tag: ```html ``` The dashboard list and the page-level list are combined — the page can only **add** to the protected list, never remove dashboard-managed terms. Once a term is stable, move it into the dashboard so every page on every site picks it up automatically. *** ## When to use each option [#when-to-use-each-option] | You want to… | Use this | | --------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | | Keep a single block (e.g. a footer) untranslated | [`data-translate-skip`](/docs/translate/excluding-content) on the wrapping element | | Keep a brand name untranslated everywhere it appears | **Never Translate Terms** in the dashboard | | Keep a drug or product name consistent across all languages | **Never Translate Terms** in the dashboard | | Protect a term on a single page without touching the dashboard | `window.OURS_NO_TRANSLATE_TERMS` on that page | | Provide a custom translation for a specific term (e.g. "Login" → "Acceder") | Not currently supported — [contact support](mailto:support@oursprivacy.com) to discuss | *** ## Troubleshooting [#troubleshooting] ### A term is still being translated [#a-term-is-still-being-translated] * Confirm the term is saved in the **Never Translate Terms** list and you clicked **Save Changes**. * Hard-reload the page so the widget re-fetches the latest configuration. * Check that the string matches what appears on the page (the widget matches the literal text — punctuation, hyphens, and trademark symbols all count). ### A term I did not configure is being preserved [#a-term-i-did-not-configure-is-being-preserved] * Check whether it is a substring of a configured term. `Acme` will match inside `AcmeCorp`; remove the shorter term or add `AcmeCorp` as a more specific entry. ### Performance [#performance] The list is matched against page text once per translation request. Hundreds of terms are fine. Keep the list scoped to terms that genuinely need protection. *** ## Next Steps [#next-steps] * [Exclude entire elements](/docs/translate/excluding-content) from translation * [Common questions](/docs/translate/faqs) # Supported Languages [#supported-languages] The Translation Widget supports 75 languages, covering major world languages and regional variants. *** ## Language List [#language-list] | Language | Code | Language | Code | | --------------------- | ------- | --------------------- | ------- | | Afrikaans | `af` | Lithuanian | `lt` | | Albanian | `sq` | Macedonian | `mk` | | Amharic | `am` | Malay | `ms` | | Arabic | `ar` | Malayalam | `ml` | | Armenian | `hy` | Maltese | `mt` | | Azerbaijani | `az` | Marathi | `mr` | | Bengali | `bn` | Mongolian | `mn` | | Bosnian | `bs` | Norwegian (Bokmål) | `no` | | Bulgarian | `bg` | Pashto | `ps` | | Catalan | `ca` | Polish | `pl` | | Chinese (Simplified) | `zh` | Portuguese (Brazil) | `pt` | | Chinese (Traditional) | `zh-TW` | Portuguese (Portugal) | `pt-PT` | | Croatian | `hr` | Punjabi | `pa` | | Czech | `cs` | Romanian | `ro` | | Danish | `da` | Russian | `ru` | | Dari | `fa-AF` | Serbian | `sr` | | Dutch | `nl` | Sinhala | `si` | | English | `en` | Slovak | `sk` | | Estonian | `et` | Slovenian | `sl` | | Farsi (Persian) | `fa` | Somali | `so` | | Filipino (Tagalog) | `tl` | Spanish | `es` | | Finnish | `fi` | Spanish (Mexico) | `es-MX` | | French | `fr` | Swahili | `sw` | | French (Canada) | `fr-CA` | Swedish | `sv` | | Georgian | `ka` | Tamil | `ta` | | German | `de` | Telugu | `te` | | Greek | `el` | Thai | `th` | | Gujarati | `gu` | Turkish | `tr` | | Haitian Creole | `ht` | Ukrainian | `uk` | | Hausa | `ha` | Urdu | `ur` | | Hebrew | `he` | Uzbek | `uz` | | Hindi | `hi` | Vietnamese | `vi` | | Hungarian | `hu` | Welsh | `cy` | | Icelandic | `is` | | | | Indonesian | `id` | | | | Irish | `ga` | | | | Italian | `it` | | | | Japanese | `ja` | | | | Kannada | `kn` | | | | Kazakh | `kk` | | | | Korean | `ko` | | | | Latvian | `lv` | | | *** ## Priority Languages [#priority-languages] The widget automatically displays these 5 languages at the top of the selection list: 1. English (`en`) 2. Spanish (`es`) 3. French (`fr`) 4. German (`de`) 5. Chinese Simplified (`zh`) All other enabled languages appear alphabetically below. *** ## Language Display [#language-display] In the widget modal, each language shows: * **Country flag** (emoji) * **English name** (e.g., "Spanish") * **Native name** (e.g., "Español") Visitors can search/filter languages by any of these properties. *** ## Selecting Languages for Your Widget [#selecting-languages-for-your-widget] When configuring your widget, consider: ### Audience Analysis [#audience-analysis] * What languages do your website visitors speak? * Where is your traffic coming from geographically? * What languages does your customer support team handle? ### Healthcare Considerations [#healthcare-considerations] For US healthcare organizations, common language needs include: * Spanish (`es`) - Largest non-English speaking population * Chinese (`zh`) - Significant in many urban areas * Vietnamese (`vi`) - Large population in certain regions * Tagalog (`tl`) - Filipino communities * Korean (`ko`) - Korean-American communities * Arabic (`ar`) - Growing population * Russian (`ru`) - Eastern European communities ### Legal & Compliance [#legal--compliance] Some regions require content availability in specific languages. Check local regulations for: * Patient communication requirements * Accessibility mandates * Language access laws *** ## Requesting New Languages [#requesting-new-languages] If you need a language not currently supported, contact [support@oursprivacy.com](mailto:support@oursprivacy.com). *** ## Next Steps [#next-steps] * [Configure your widget](/docs/translate/configuration) * [Common questions](/docs/translate/faqs) What the player handles for you, and which accessibility choices are yours when you generate an embed. Healthcare and public-sector sites are frequently held to WCAG Level AA, and video is one of the places accessibility reviews look first. The player conforms to WCAG 2.2 Level AA and Section 508, so it satisfies both the current standard and the earlier 2.1 version that many procurement checklists still name. Most of what a review asks for is either built in or a matter of the settings you pick when you generate the embed. *** ## Captions [#captions] Every uploaded video is transcribed in its selected source language and the player picks the caption file up automatically, so captions are available without extra setup. Add translated or professionally provided tracks for the languages your audience needs. Automatic transcription is not perfect, and an inaccurate caption track can be worse than none for someone who depends on it, so review captions before publishing anything where accuracy matters. Viewers control caption appearance themselves through the player's caption settings, so there is nothing to style. See [Captions and transcripts](/docs/video/captions-and-transcripts) for the editor and [Caption vocabulary](/docs/video/caption-vocabulary) for improving first-pass accuracy on your own terminology. The player mid-playback with a caption line rendered over the video and the full control bar visible, including the captions and fullscreen buttons Audio description is not generated. If a video conveys information visually that the narration does not state, provide it another way, such as a described version or an on-page transcript. *** ## Keyboard and screen readers [#keyboard-and-screen-readers] The player is built on Video.js, so its controls are reachable by keyboard and labeled for assistive technology out of the box: the play button, progress bar, volume, playback speed, captions, and fullscreen are all focusable and operable without a mouse. The playback speed control follows the same pattern as a standard menu button. It can receive focus, Enter or Space opens the rate menu, arrow keys move between the available rates, and Enter selects one. The menu is exposed as `role="menu"`, and each rate is a `role="menuitemradio"` whose `aria-checked` state reflects the rate currently playing, so a screen reader announces which speed is active. In a **Popup** embed, Escape closes the lightbox wherever focus is, including on a control inside the player. It is applied in order: anything already open inside the player (a player menu, the caption settings dialog, or an engagement interaction the viewer can decline) takes the first Escape, and the next press closes the lightbox. A visitor dismissing a menu never loses the video by accident. There are two exceptions. While the player is fullscreen, Escape leaves fullscreen instead. A locked engagement interaction does not take Escape at all, so Escape remains the way out of a video the viewer has decided not to complete. The player loads in a frame on your page, and the generated snippet already gives that frame a label built from the video's description, or from its title if there is no description. Screen reader users hear that label when they reach the player, so fill in the video's description before copying the snippet rather than leaving the generic fallback in place. See [Updating a video](/docs/video/updating-a-video). *** ## Color contrast [#color-contrast] The **Player color** you choose drives the play button, control bar, and progress bar. The dashboard checks it against a WCAG AA 4.5:1 contrast minimum and warns when the combination falls short, so you find out before publishing rather than during an audit. The player derives its matching foreground and hover shades from that one value, so you cannot end up with a mismatched pair by hand. If you see the contrast warning, pick a darker or lighter variant of your brand color rather than overriding it on the page. The Embed tab with a low-contrast Player color highlighted and a WCAG AA 4.5:1 warning explaining how to correct it *** ## Embed choices that affect accessibility [#embed-choices-that-affect-accessibility] These options in [Embed configuration](/docs/video/embed-configuration) carry accessibility consequences: * **Show controls off** removes the viewer's ability to pause, mute, change playback speed, or turn on captions. Only use it for decorative video that is muted, looping, and carries no information the viewer needs. * **Autoplay on** starts motion the viewer did not ask for, and the player is muted automatically as a result. Keep the controls visible so anyone who needs to stop it can. * **Loop on** means motion never stops on its own. Pair looping background video with a still poster or a static alternative where you can, and keep the loop short. * **Keep playing while scrolling on** is motion that follows the viewer down the page. The floating player's **Close floating video** button is how someone gets that motion out of their way, and it leaves playback running. The player moves without animation for a viewer who has set a reduced-motion preference, and the option is only offered with controls on and autoplay off, so pausing is always available. Avoid pairing it with an automatic lightbox trigger on the same page, where two things would compete for attention. * **Time on page and URL parameter** open a modal while the visitor may be reading or completing another task. Prefer Thumbnail or Text link for informational video. If you use an automatic trigger, keep controls visible and test that the lightbox does not compete with another modal or form step. A safe default for informational video is controls on, autoplay off, loop off, with reviewed captions. *** ## Lead capture and CTA interactions [#lead-capture-and-cta-interactions] The [Video Lead Capture](/docs/video/lead-capture) overlay keeps keyboard focus within the interaction while it is visible. Before playback, the email field receives focus. At the midpoint, continuing returns focus to the player. After completion, replay returns focus to the player as playback begins. An unlocked interaction includes a clear continue or replay control. A locked interaction intentionally has no in-player way to continue or replay without completing its primary action, so use it only when that requirement is appropriate for the page. *** ## Conformance [#conformance] The Ours Privacy Video Player is built to meet modern accessibility standards. Playback controls are keyboard navigable and screen reader compatible, captions are supported, and the player conforms to **WCAG 2.2 Level AA** and **Section 508**. *** ## Related pages [#related-pages] * [Captions and transcripts](/docs/video/captions-and-transcripts): review and correct the caption track. * [Embed configuration](/docs/video/embed-configuration): every option and its default. * [Video Lead Capture](/docs/video/lead-capture): configure accessible email capture and CTA interactions. * [Recipes](/docs/video/recipes): accessible combinations for common placements. The events the video player reports, their properties, and the conditions under which each fires. For reading the report built on them, see [Video Analytics](/docs/video/video-analytics). Event names and property names follow the GA4 video conventions, so they line up with video reporting you may already have elsewhere. *** ## Events [#events] | Event | Fires when | | ---------------- | ---------------------------------------------------------------- | | `video_start` | Playback begins for the first time in the player's current cycle | | `video_progress` | Playback crosses 10%, 25%, 50%, or 75% | | `video_complete` | Playback reaches the end | *** ## Properties [#properties] Every video event carries the same property set. | Property | Type | Description | | -------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `video_id` | string | Identifier of the video in your Ours Privacy account | | `video_title` | string | The video's title as set in the dashboard | | `video_url` | string | URL of the video file being played | | `video_provider` | string | Always `oursprivacy` | | `video_duration` | number | Total length in whole seconds | | `video_current_time` | number | Playback position in whole seconds when the event fired | | `video_percent` | number | Playback position as a whole-number percentage | | `visible` | boolean | Whether the page was in the foreground when the event fired. `false` means the visitor had the tab in the background, which separates real watching from playback nobody was looking at | *** ## `video_start` [#video_start] Fires on the first play of a cycle. Pausing and resuming does not fire another one, so starts count views rather than play button presses. A replay of a non-looping video does fire a new `video_start`. With [autoplay](/docs/video/embed-configuration) on, the start fires as soon as the browser permits playback, so starts count muted autoplayed impressions alongside deliberate plays. On an autoplaying video, start volume tracks page views more than interest. Judge it by how far viewers get. *** ## `video_progress` [#video_progress] Fires at 10%, 25%, 50%, and 75%, once each per cycle. * **Skipping ahead skips the milestones in between.** Jumping from 5% to 80% does not fill in 10%, 25%, and 50%. Progress reflects positions actually played through, not the furthest point reached. A drop between two milestones can therefore mean viewers skipped forward rather than left. * **Milestones fire on the whole percentage**, so a very short video can miss one if playback jumps past it between position updates. Read together, the milestones give the drop-off shape [Video Analytics](/docs/video/video-analytics) does not show: the share of starts still watching at 25% against 75% tells you where a video loses people. *** ## `video_complete` [#video_complete] Fires when playback reaches the end, reporting `video_percent` as `100`. On a [looping](/docs/video/embed-configuration) video, the player reports one `video_complete` on the first full pass and then stays silent for every later loop. A looping background video therefore contributes one view and one completion rather than an event every few seconds. Progress milestones also stop after that first pass. *** ## Lead capture and CTA activity [#lead-capture-and-cta-activity] When you configure [Video Lead Capture](/docs/video/lead-capture), Video Analytics also records lead capture displays, completed lead captures, CTA displays, and CTA clicks. These private reporting signals are built into the player and do not appear as events for you to add to an Allowed Events list. After a visitor submits a valid email, the player also sends the standard `form_submit` event. Allow and map `form_submit` to send completed video forms to a destination. It includes the video and interaction context, while the visitor's email is handled as visitor data rather than an event property. *** ## Where the events go [#where-the-events-go] The player reports playback to the Ours Privacy Web SDK on the page hosting the embed. From there the events behave like any other event you track: * They appear in [Video Analytics](/docs/video/video-analytics) and in Recent Events. * They can be allowed and mapped to [destinations](/docs/destination-overview), which is how you get video engagement into an ad platform, a warehouse, or your own analytics. * They pass through the same [data governance](/docs/global-data-governance) rules as the rest of your events. A single video's Video Analytics report showing views, viewer sessions, completion rate, total completions, and the daily engagement chart The events arrive only when both of these hold: * The **Web SDK must be installed on the page** hosting the embed. Without it there is nothing to receive playback events, and the video still plays normally. * The embed must be **the snippet copied from the dashboard**. A player of your own reports nothing; see [Building your own player](/docs/video/custom-player). *** ## Related pages [#related-pages] * [Video Analytics](/docs/video/video-analytics): the report built on these events. * [Video Lead Capture](/docs/video/lead-capture): configure an email capture or CTA. * [Embed configuration](/docs/video/embed-configuration): options that change what gets reported. * [Web SDK](/docs/web-sdk-javascript): installing the SDK on the hosting page. Improve how automatic captions handle terms specific to your organization: provider names, facility names, program names, and clinical vocabulary. Automatic transcription handles everyday speech well and struggles with words it has never seen. A caption vocabulary is a list of those words, shared across every video in your account. *** ## Add your terms [#add-your-terms] 1. Go to **Videos** in the dashboard and choose **Caption Vocabulary**. 2. Enter one term per line. 3. Choose **Save vocabulary**. The Caption Vocabulary dialog showing an Active status, eight provider and clinical terms entered one per line, a note that protected health information does not belong here, and a Save vocabulary button Your organization's name is always included, so you do not need to add it. Good candidates are the words automatic captions currently get wrong: facility and program names, branded patient portals, provider surnames, procedure and medication names, and local place names. *** ## When it takes effect [#when-it-takes-effect] Saving the vocabulary starts a short build. Reopening **Caption Vocabulary** shows the current state: * **Building.** The list is being prepared. New uploads use it once the build finishes, usually within a few minutes. * **Active.** New uploads are transcribed with these terms. * **Could not be built.** Save again to retry. Captions on your videos are unaffected either way. The vocabulary applies to videos uploaded from that point on. It does not re-caption videos you have already uploaded. To apply new terms to an existing video, either re-upload it or correct that video's captions directly in the [caption editor](/docs/video/captions-and-transcripts). *** ## Do not enter PHI [#do-not-enter-phi] Do not enter patient names, medical record numbers, or any other protected health information. This list is transcription configuration, not patient data, and it is shared across every video in your account. Terms are also limited in count and length. If you have more candidate terms than the field accepts, prioritize the ones that appear most often across your video library. *** ## Next steps [#next-steps] * [Captions and transcripts](/docs/video/captions-and-transcripts): review and correct captions on a specific video. * [Uploading videos](/docs/video/uploading-videos): upload a video so the vocabulary applies to it. * [Video FAQs](/docs/video/faqs): common questions about captions and languages. Use this page to review, correct, or replace the captions on a video. *** ## Automatic captions [#automatic-captions] When you upload a video, choose its source language. The audio is transcribed into that language and saved as a caption file in the standard VTT format. The player picks the file up automatically, so captions are available to viewers without any further setup. A caption file is a list of **cues**. Each cue is one line of on-screen text plus the moment it appears and the moment it goes away. * **Review automatic captions.** Automatic transcription can still misrender clinical terms and proper nouns. Add terms to your [caption vocabulary](/docs/video/caption-vocabulary) and review the source track before publishing. * **Videos over 2 GB skip transcription.** Upload your own caption file for those, using the steps below. The **Captions** section on the video detail page shows which state a video is in: **Auto-generated**, **Uploaded** (a person supplied or edited the file), or **None**. The Captions section of a video detail page showing captions are uploaded, with controls to edit, download, or replace the caption file *** ## Correct captions in the dashboard [#correct-captions-in-the-dashboard] The caption editor lets you fix wording and timing one cue at a time, against the video as it plays. 1. Open the video and find the **Captions** section. 2. Choose **Edit captions**. 3. Play the video. The active cue is highlighted and shown over the player as it plays. 4. Edit any cue's text directly in its row. 5. Adjust timing by typing a timestamp, or by moving the playhead to the right moment and choosing **Set start** or **Set end**. 6. Add missing lines with **Add cue**, and remove stray ones with the row's delete control. 7. Choose **Save captions**. The caption editor with the video preview and current playhead time above a list of cue rows, each holding the caption text and its start and end timestamps Saved captions replace the selected track the player serves. The editor blocks saving while a cue has an invalid time range, so fix any flagged rows first. To get consistently better first-pass results on terms specific to your organization, add them to your [caption vocabulary](/docs/video/caption-vocabulary) before uploading. *** ## Add another language [#add-another-language] Use the **Captions** section to add another language: 1. Choose **Translate captions** and select a target language, or choose **Upload track** to provide a VTT or SRT file you already have. 2. Wait for the track to show **Ready**. 3. Choose a language from the track list to edit or download its captions. The player lists every ready track in its captions menu. It uses the viewer's browser language when a matching track exists, otherwise it uses the source track. *** ## Upload your own caption file [#upload-your-own-caption-file] If you caption elsewhere, upload the finished file for the source language or another language: 1. Open the video and find the **Captions** section. 2. Choose **Upload your own** (or **Replace** if the video already has uploaded captions). 3. Pick a **VTT** or **SRT** file. SRT files are converted to VTT during upload. Uploading replaces the selected language track. It does not change the other tracks. *** ## Download the caption file [#download-the-caption-file] Choose the download control in the **Captions** section to save the current VTT file. This is useful for editing in a dedicated captioning tool, having captions reviewed, or reusing the transcript elsewhere on the page. *** ## Captions and accessibility [#captions-and-accessibility] Captions are one of the clearest accessibility wins on a video. * Review automatic captions before publishing anything where accuracy matters. * Viewers control caption appearance themselves through the player's caption settings, so you do not need to style them. * Captions only help if the viewer can reach them, which means leaving the player controls visible. See [Player accessibility](/docs/video/accessibility). *** ## Next steps [#next-steps] * [Caption vocabulary](/docs/video/caption-vocabulary): teach automatic captions the terms your organization uses. * [Player accessibility](/docs/video/accessibility): how captions render and what else the player supports. * [Updating a video](/docs/video/updating-a-video): replace assets and clear caches after a change. * [Building your own player](/docs/video/custom-player): use the caption file URL in a player of your own. Use this page when the standard embed does not fit and you want to render the video yourself. The standard embed snippet is the supported path and handles playback, captions, styling, and analytics for you. Reach for raw assets when you need something the player does not offer, such as a design-system video component, a native mobile player, or playback inside an app shell. *** ## Get the asset URLs [#get-the-asset-urls] 1. Open the video in the dashboard. 2. Open the **Embed** tab and find the **Custom Player Assets** section. 3. Copy the URLs you need: **MP4 URL**, **VTT URL** (captions), and **Poster URL**. The Custom Player Assets tab listing the MP4, VTT, and poster URLs for a video, each with a copy control These URLs are stable and cached for fast delivery. They keep working when you replace captions or the poster image, so you do not need to re-copy them after an update; see [Updating a video](/docs/video/updating-a-video). *** ## Use them in a player [#use-them-in-a-player] Any player or `