Exposure sources let you send ad-exposure data into MX8 Labs so it can be matched against survey respondents. Before setting one up, it is worth checking that the campaign is large enough to measure: Campaign size and measurability converts impressions, frequency and audience size into the respondent sample a lift study would need. This is the foundation of ad-effectiveness research - by linking who saw an ad with how they responded to a survey, you can measure real-world campaign impact.
How exposure data works
Every time a person is exposed to an ad, a record is created that captures an IP address (plaintext or hashed) plus the identifiers you configure — typically a user identifier (UID) and dimensions such as the brand associated with the ad, both of which are optional. Using the identifiers supplied with your exposure records, MX8 Labs determines whether a survey respondent was exposed, so you can compare exposed and unexposed audiences.
Two ways to send exposure data
MX8 Labs supports two ingest methods. Which one you choose depends on where your exposure data originates and how much control you need over the delivery process.
Pixel - A lightweight tracking endpoint hosted by MX8 Labs. You embed a pixel URL in your ad server or tag manager, and each time the pixel fires it captures an exposure event in real time. Pixel sources are ideal when you want a quick, low-integration setup and your ad platform supports third-party pixel calls.
S3 snapshot - A server-side file-based approach. You upload gzip-compressed CSV files containing exposure records directly into an MX8 Labs-managed S3 bucket. S3 snapshot sources are ideal when you already collect exposure data in your own systems and prefer to send it in batch, or when you need to hash IP addresses before they leave your environment.

The two source types also have different monitoring views. Pixel sources provide hourly delivery metrics such as impressions and UID presence. S3 sources provide per-file ingest history with Total, Retained, Imported, and Rejected row counts. See Exposure Source Reporting and Monitoring S3 Exposure Ingests.
Key terminology
- Source name - A human-readable label for your exposure source. Once created, this cannot be changed.
- Dimension - An additional attribute you attach to each exposure record (for example,
brand). Dimensions are used as query-parameter keys for pixels and as aggregation buckets in reporting. - Retention days - How long MX8 Labs keeps exposure records for matching. You set this when creating the source — choose a window that suits your campaign timeline.
- UID - Your user identifier, up to 128 characters, sent alongside each exposure record.
- Hashed IP - An IP address that has been run through a hashing algorithm (currently MD5) before being sent to MX8 Labs. This lets you avoid transmitting plaintext IP addresses.
Using exposure data in your survey
Call s.get_exposures(source=..., id=...) to retrieve the current respondent's exposure records. Each record keeps its dimensions together, so you can distinguish a particular campaign and creative combination instead of matching unrelated values from separate lists.
For a source configured with campaign and creative dimensions:
from survey import Survey
s = Survey(**globals())
exposures = s.get_exposures(source="campaign-123", id="ad-exposures")
saw_target_creative = any(
exposure.campaign == "campaign-a" and exposure.creative == "creative-b"
for exposure in exposures
)
with s.tag(exposed=saw_target_creative):
s.select_question(
"How familiar are you with this brand?",
options=["Very familiar", "Somewhat familiar", "Not familiar"],
)
s.complete()
The exposed tag marks questions in the block for the chosen comparison. Select it as the Indicator Tag when setting up a lift report. Use dimension names and values that match your source configuration.
Reporting, recency and frequency
The returned list is reportable. Each record carries its dimension attributes, frequency, and exposure_source; days_since_exposure is also available when recency information exists. Use those attributes in survey logic and reporting. An empty list means no matching exposure records were returned.
To mark survey media as exposed, use s.tag_exposed_media(...). See Media functions for that separate workflow.
For new surveys, use get_exposures instead of the deprecated get_exposed_values. The older method returns values for one dimension and does not preserve relationships between dimensions.
Testing exposure routes with simulations
Survey simulations support exposure-based routes using samples from the configured exposure sources. Call each exposure lookup unconditionally before branching or ending the survey, with a fixed source name, so simulation can discover the sources it needs.
Simulated exposure combinations are synthesized from sampled dimension values. Use them to test survey routes and report structure; they are not evidence that a real respondent saw that combination of ads. Check both exposed and unexposed paths before fielding.
See Reporting lift against control groups for the analysis setup.
Next steps
- Creating a Pixel Exposure Source - set up real-time tracking in minutes.
- Creating an S3 Snapshot Exposure Source - configure server-side batch delivery.
