Retail Signal Enrichment Mapping
How do you resolve retail signals to specific companies and identify decision-makers?
Purpose
This recipe transforms raw retail distress signals (inventory anomalies, job posting patterns, SEC filing keywords, satellite data) into enriched company profiles with verified decision-maker contacts. The output is a structured database mapping each detected signal to a specific company, its firmographic profile, and the 2-3 people most likely to authorize a purchase — ready for outreach sequence loading. [src3, src5]
Prerequisites
- Detected signal report available from
signal-library/retail/detection-rules/2026— Retail Detection Rules - Company identifiers (domain, name, or filing entity) extracted from signal sources — SEC Financial Filings
- Apollo.io API key — API key from Apollo.io (free tier: 50 credits/month)
- Hunter.io API key — API key from Hunter.io (free tier: 25 searches + 50 verifications/month)
- LinkedIn Sales Navigator account (optional) — from LinkedIn Sales Solutions ($99/month)
- Dropcontact account (required for EU targets) — from Dropcontact ($24/month)
- Python 3.10+ or Node.js 18+ installed with HTTP client library (requests/axios)
Constraints
- GDPR: Do not scrape personal emails of EU-based retail executives without documented legitimate interest basis. Use Dropcontact (GDPR-compliant by design) for EU contacts rather than Apollo.io or Hunter.io. [src1]
- CAN-SPAM: All US outreach emails must include physical address, functioning unsubscribe mechanism, and non-deceptive subject lines. Penalties are $51,744 per non-compliant email. [src2]
- Do not target contacts below Director level. Retail technology and operations purchases require VP+ approval authority. Targeting managers wastes enrichment credits and damages sender reputation. [src3]
- Contact data expires after 90 days. Retail VP+ turnover is 18-22% annually, and 30-40% of role changes occur without public announcement. Schedule re-enrichment every quarter. [src4]
- Apollo.io rate limit: 100 requests/minute on paid plans, 10 requests/minute on free tier. Batch requests and add sleep intervals to avoid 429 errors. [src5]
- Hunter.io verification: Free tier allows 50 verifications/month. Budget $49/month for Hunter.io if verifying more than 50 contacts per batch. [src6]
Tool Selection Decision
Which path?
├── Budget = free tier only
│ └── PATH A: Free — Apollo.io free (50 credits) + Hunter.io free (50 verifications)
├── Budget = up to $200/month AND region = US only
│ └── PATH B: Paid US — Apollo.io Basic ($49) + Hunter.io Starter ($49) + LinkedIn Sales Nav ($99)
├── Budget = up to $200/month AND region includes EU
│ └── PATH C: Paid EU-Compliant — Apollo.io Basic ($49) + Dropcontact ($24) + Hunter.io Starter ($49)
└── Budget = $500+/month (enterprise)
└── PATH D: Enterprise — Apollo.io Professional ($99) + LinkedIn Sales Nav ($99) + Dropcontact ($96) + Hunter.io Growth ($99)
| Path | Tools | Cost | Speed (50 companies) | Output Quality |
|---|---|---|---|---|
| A: Free | Apollo.io free + Hunter.io free | $0 | 2-3 hours | Basic — 50 credits limits depth, ~60% email coverage |
| B: Paid US | Apollo.io + Hunter.io + LinkedIn | $197/mo | 30-45 min | High — full firmographic + verified contacts, US-optimized |
| C: Paid EU | Apollo.io + Dropcontact + Hunter.io | $122/mo | 45-60 min | High — GDPR-compliant EU contacts, full firmographic |
| D: Enterprise | Full stack | $393/mo | 20-30 min | Excellent — multi-source verification, deepest coverage |
Execution Flow
Step 1: Company Resolution
Duration: 10-15 minutes per 50 signals · Tool: Python/Node.js script + signal source data
Resolve raw signal data to specific company identities. Each signal type produces different identifiers that must be mapped to a canonical company record.
- Job posting signals: Extract domain from posting URL (e.g., careers.target.com → target.com). Resolution confidence: 0.95.
- SEC filing signals: Map CIK number to company via SEC EDGAR lookup. Resolution confidence: 0.99.
- WARN notice signals: Match company name from WARN filing directly. Resolution confidence: 0.90.
- Foot traffic / satellite signals: Geocode lat/lon coordinates to nearest corporate HQ, then look up parent company. Resolution confidence: 0.75-0.85.
Verify: Each resolved company has a company_name and either a domain or CIK identifier. Resolution confidence > 0.80 for all entries. · If failed: For signals with confidence < 0.80, run manual lookup via Apollo.io company search using company name + location.
Step 2: Firmographic Enrichment
Duration: 10-15 minutes per 50 companies · Tool: Apollo.io API
Rate limit: Free tier: 10 req/min. Paid tier: 100 req/min. Sleep 1s between requests on free tier.
Enrich resolved companies using Apollo.io organization enrichment endpoint. Use domain enrichment (highest accuracy) when domain is available, fall back to name search otherwise.
Fields to capture: company_name, domain, HQ location (city/state/country), employee_count, annual_revenue_estimate, industry, LinkedIn URL, phone.
Verify: > 80% of companies have employee_count and annual_revenue_estimate populated. Domain field populated for > 90%. · If failed: If Apollo.io returns sparse data (< 60% field coverage), supplement with Clearbit Enrichment API as secondary source.
Step 3: Retail-Specific Fields
Duration: 5-10 minutes per 50 companies · Tool: Apollo.io technographics + manual web research
Augment firmographic data with retail-specific fields not available from standard enrichment APIs:
- Store count: From SEC 10-K filings, company press releases, NRF/Chain Store Age databases
- Ecommerce presence: DTC website (domain check), Amazon seller status, Shopify/Magento detection via BuiltWith, other marketplace channels (Walmart, Target+)
- Primary retail category: Apparel, grocery, electronics, home goods, specialty, etc.
- Tech stack signals: Inferred from job postings (Salesforce, SAP, Oracle, Shopify, Magento mentions in engineering titles)
- Current vendors inferred: From tech stack detection + job posting analysis (e.g., "Senior Salesforce Developer" → current Salesforce customer)
Verify: At least 3 of 5 retail-specific fields populated per company. · If failed: Flag companies with < 3 fields for manual research using SEC 10-K, SimilarWeb, and BuiltWith.
Step 4: Decision-Maker Identification
Duration: 10-15 minutes per 50 companies · Tool: Apollo.io people search + LinkedIn Sales Navigator
Identify 2-3 decision-makers per company based on the signal type that triggered enrichment:
| Signal Type | P1 Targets (Primary) | P2 Targets (Secondary) |
|---|---|---|
| Inventory / Supply Chain | VP Supply Chain, Chief Merchandising Officer | COO |
| Digital Transformation | CTO, VP Digital, Head of Ecommerce | CMO |
| AI Readiness | Chief Data Officer, VP Analytics, CTO | Chief Digital Officer |
| Store Operations | COO, VP Retail Operations | CFO, VP Real Estate |
| Mixed / Compound | COO, CTO, Chief Digital Officer | CFO, CEO |
Search Apollo.io with organization domain + person titles + seniority filter (VP, C-suite, Director). [src5]
Verify: At least 1 P1 contact identified for > 75% of companies. All contacts are Director-level or above. · If failed: Use LinkedIn Sales Navigator manual search for gap companies: filter by company + seniority (VP+) + function.
Step 5: Contact Verification
Duration: 5-10 minutes per 50 contacts · Tool: Hunter.io (US contacts) + Dropcontact (EU contacts)
Rate limit: Hunter.io: 10 verifications/second on paid plans.
Verify all email addresses before adding to final output. Use Hunter.io for US contacts and Dropcontact for EU contacts (GDPR compliance). [src6]
- Accept emails with Hunter.io score ≥ 85 as verified
- For emails scoring 50-84, keep the contact but mark email as unverified and set LinkedIn as fallback channel
- Drop contacts with email score < 50 AND no LinkedIn URL
- Flag all disposable and webmail addresses for removal
Verify: Email verification rate > 75% (verified emails / total emails attempted). No disposable or webmail addresses in final list. · If failed: If verification rate < 60%, enrichment source data may be stale. Re-run Step 4 with LinkedIn Sales Navigator as primary source.
Step 6: Output Generation
Duration: 5 minutes · Tool: Python script
Generate final enriched company profiles and decision-maker contact list in structured format.
Output files:
enriched_companies_{timestamp}.json— Full firmographic profiles with retail-specific fields, sorted by signal scoredecision_makers_{timestamp}.csv— Verified contacts with role, email, LinkedIn, priority tier, signal relevance- Console output — Summary statistics and quality metrics
Output Schema
{
"output_type": "enriched_retail_signal",
"format": "JSON + CSV",
"company_columns": [
{"name": "company_name", "type": "string", "required": true},
{"name": "domain", "type": "string", "required": true},
{"name": "hq_country", "type": "string", "required": true},
{"name": "employee_count", "type": "number", "required": true},
{"name": "annual_revenue_estimate", "type": "string", "required": true},
{"name": "store_count", "type": "number", "required": false},
{"name": "ecommerce_presence", "type": "object", "required": false},
{"name": "primary_retail_category", "type": "string", "required": true},
{"name": "tech_stack_signals", "type": "array", "required": false},
{"name": "current_vendors_inferred", "type": "array", "required": false}
],
"contact_columns": [
{"name": "full_name", "type": "string", "required": true},
{"name": "title", "type": "string", "required": true},
{"name": "email", "type": "string", "required": false},
{"name": "email_verified", "type": "boolean", "required": true},
{"name": "linkedin_url", "type": "string", "required": false},
{"name": "priority", "type": "string", "required": true},
{"name": "signal_relevance", "type": "string", "required": true}
],
"expected_row_count": "100-150 contacts for 50 companies",
"sort_order": "priority ascending, then company_name",
"deduplication_key": "email OR linkedin_url"
}
Quality Benchmarks
| Quality Metric | Minimum Acceptable | Good | Excellent |
|---|---|---|---|
| Company resolution rate | > 70% of signals resolved | > 85% resolved | > 95% resolved |
| Firmographic completeness | > 60% fields populated | > 80% populated | > 90% populated |
| Email verification rate | > 65% verified | > 80% verified | > 90% verified |
| P1 contact coverage | > 60% of companies have P1 | > 75% have P1 | > 90% have P1 |
| Duplicate rate | < 5% | < 2% | < 0.5% |
| Director+ title accuracy | > 85% at Director+ level | > 90% | > 98% |
If below minimum: Re-run Step 2 with Clearbit as secondary enrichment source. If P1 contact coverage is low, supplement with LinkedIn Sales Navigator manual search for gap companies.
Error Handling
| Error | Likely Cause | Recovery Action |
|---|---|---|
| Apollo.io 429 (rate limit) | Too many requests in time window | Wait 60 seconds, reduce batch size to 5 per minute on free tier |
| Apollo.io 401 (auth failed) | API key expired or invalid | Regenerate API key at apollo.io/settings, update config |
| Hunter.io returns "accept_all" | Company mail server accepts all addresses | Treat as unverified — use LinkedIn as primary channel |
| Empty Apollo.io results | Company too small or not in database | Try Clearbit enrichment, or manual LinkedIn company search |
| GDPR region detected, non-compliant tool | EU company routed through Apollo.io | Re-route EU contacts through Dropcontact pipeline |
| Duplicate contacts across companies | Same person at multiple subsidiaries | Deduplicate by email + LinkedIn URL; keep parent company record |
| SEC CIK lookup returns no match | Company is private or different filing entity | Fall back to company name fuzzy match + domain enrichment |
Cost Breakdown
| Component | Free Tier | Paid Tier | At Scale (500 companies) |
|---|---|---|---|
| Company enrichment (Apollo.io) | 50 credits/mo (50 companies) | $49/mo = 500 credits | $99/mo = 2000 credits |
| People search (Apollo.io) | Included in credits | Included | Included |
| Email verification (Hunter.io) | 50 verifications/mo | $49/mo = 1000 verifications | $99/mo = 5000 verifications |
| LinkedIn Sales Navigator | N/A | $99/mo | $99/mo |
| EU contacts (Dropcontact) | N/A | $24/mo = 1000 contacts | $96/mo = 5000 contacts |
| Total for 50 companies | $0 | $147-$221/mo | $393/mo |
Anti-Patterns
Wrong: Enriching before resolving
Sending raw signal data (lat/lon coordinates, SEC CIK numbers, job posting URLs) directly to enrichment APIs without first resolving to a canonical company identity. Result: duplicate records, mismatched firmographics, and wasted API credits when the same company appears via multiple signal types under different identifiers. [src5]
Correct: Resolution-first pipeline
Always run Step 1 (Company Resolution) first to create a deduplicated company list with canonical identifiers. Then enrich once per company, not once per signal.
Wrong: Skipping email verification
Loading unverified email addresses directly into outreach sequences. Result: 15-25% bounce rate, sender domain reputation damage, potential blacklisting by ESPs, and all future emails routed to spam. [src6]
Correct: Verify everything, fallback to LinkedIn
Run all emails through Hunter.io or equivalent verification. Remove emails scoring below 85% confidence. For contacts with no verified email, use LinkedIn InMail or connection request as fallback channel.
Wrong: One-size-fits-all targeting
Using the same decision-maker titles regardless of signal type. Sending supply chain distress signals to the CTO, or AI readiness signals to the VP Supply Chain. Result: irrelevant outreach, low response rates, and wasted contacts. [src3]
Correct: Signal-to-role mapping
Use the signal-type-to-role mapping table (Step 4) to route each signal type to the correct decision-maker function. Inventory signals go to VP Supply Chain (P1) and COO (P2). Digital transformation signals go to CTO and VP Digital (P1) and CMO (P2).
When This Matters
Use this recipe when raw retail distress signals have been detected and scored but have not yet been mapped to specific companies and contacts. This is the bridge between signal detection (upstream) and outreach execution (downstream). Without enrichment mapping, detected signals remain abstract market intelligence rather than actionable sales opportunities.