What you will build
This cookbook walks through creating an IP-to-MAID enrichment pipeline that:- Uploads a dataset of IP addresses from your server logs or web analytics
- Previews MAID data availability by type (IDFA vs GAID) across Rosetta Stone
- Matches IPs to MAIDs using an identity join against Rosetta Stone
- Ranks MAIDs by observation frequency to surface the most reliable matches
- Automates recurring enrichment with a materialized view
Prerequisites
Before starting, ensure you have:- A dataset of IP addresses uploaded to Narrative
- Familiarity with NQL syntax
- Understanding of Mobile Ad IDs (IDFA, GAID)
- Understanding of IP addresses and their limitations
- Understanding of materialized views
Step 1: Upload your IP address dataset
Upload your IP address file to Narrative. This dataset serves as the seed list you want to enrich with MAIDs. Your dataset should include at minimum:| Column | Type | Description |
|---|---|---|
ip | string | IPv4 or IPv6 address |
observed_at | timestamp | When the IP was observed in your system |
Upload your dataset through the Narrative UI or SDK. The
ip column does not need a Rosetta Stone mapping—you will join it directly against the "ip_address" attribute in Rosetta Stone.Step 2: Preview IP-to-MAID data availability
Before running the full enrichment, query Rosetta Stone to understand how much MAID coverage is available by identifier type:Step 3: Match IPs to MAIDs
Join your IP dataset against Rosetta Stone to find MAIDs observed on the same IP addresses. This is the core enrichment query:| Pattern | Purpose |
|---|---|
INNER JOIN company_data | Matches only IPs present in your seed dataset |
mobile_id_unique_identifier.value / .type | Extracts MAID value and type (IDFA or GAID) |
ip_address | Rosetta Stone’s normalized IP address attribute |
INTERVAL '45' DAY | Limits to recent observations for freshness |
A single IP address may resolve to many MAIDs—especially shared or commercial IPs. Step 4 shows how to rank and limit results to the most reliable matches.
Step 4: Rank MAIDs by observation frequency
A single IP can map to many devices, and not all associations are equally reliable. UseQUALIFY with ROW_NUMBER and a nested APPROX_COUNT_DISTINCT window function to keep only the top N most-frequently-observed MAIDs per IP:
- The inner window (
APPROX_COUNT_DISTINCT ... OVER (PARTITION BY country, ip, maid, maid_type)) counts distinct observation timestamps for each IP-MAID pair. MAIDs seen more often on an IP address get a higher count. - The outer window (
ROW_NUMBER ... OVER (PARTITION BY country, ip ORDER BY ... DESC)) ranks MAIDs within each country + IP group by that observation count, highest first. QUALIFY ... <= 3keeps only the top 3 most-frequently-observed MAIDs per IP per country.
Step 5: Add country filtering and enrichment stats
Extend the query with geographic filtering and amaid_count column that shows the total unique MAIDs found per IP before ranking. This helps you assess match quality:
maid_count column reveals IP quality:
- Low count (1-5): Likely residential IPs with a small number of devices—high-confidence matches
- High count (50+): Likely commercial, VPN, or CGNAT IPs—consider excluding these from activation
MAID type breakdown variation
To see the split between IDFA and GAID per IP, replace themaid_count window with a type-specific count:
Step 6: Automate with a materialized view
Wrap the final query in a materialized view that refreshes automatically:Adjust the
REFRESH_SCHEDULE based on how frequently your IP dataset changes. @weekly works well for server logs that update regularly. Use @monthly if your IP list is relatively static.Summary
You have built an IP-to-MAID enrichment pipeline with these components:| Query / View | Purpose |
|---|---|
| Data availability preview | Assess MAID volume and type coverage before enrichment |
| IP-to-MAID join | Core matching of IPs to mobile ad IDs via Rosetta Stone |
| Frequency-ranked results | Top N MAIDs per IP based on observation count |
ip_to_maid_enriched | Automated materialized view with country filtering and quality metrics |
Use cases
- Cross-device targeting: Reach users on mobile who were previously only identifiable by IP
- Mobile campaign activation: Build MAID-based audiences from web traffic data for DSP activation
- Device graph enrichment: Augment your identity graph with IP-to-MAID linkages
- Measurement and attribution: Connect web sessions (IP) to mobile app activity (MAID)
Key advantages
Simplified sourcing
Rosetta Stone queries all available data providers automatically—no need to identify and UNION across individual datasets
Frequency-based ranking
Nested window functions surface the most reliable IP-MAID associations, filtering out transient connections
Automated refresh
Weekly materialized views keep your MAID mappings current as new observations arrive
Quality signals
The
maid_count column helps identify commercial or shared IPs that may produce low-quality matchesImportant considerations
IP addresses as personal data: Under GDPR, IP addresses are considered personal data. Ensure your enrichment workflow complies with applicable privacy regulations, particularly when processing IPs from EU users. See GDPR compliance and CCPA compliance for details.
Related content
Mobile Ad IDs
Understanding IDFA, GAID, and privacy considerations
IP Addresses
IP address types, limitations, and best practices
Joining Datasets
Learn JOIN patterns for enrichment queries
Performance Patterns
Window functions, QUALIFY, and other advanced NQL patterns

