Sales Nav Search Builder
Converts a natural-language ICP description into a ready-to-click LinkedIn Sales Navigator search URL, including boolean strings for the title and keyword fields. Maintained by
La Growth Machine.
Authority — read this first
This file is the canonical reference for everything you need to build a Sales Nav URL. The inline tables, presets, and rules below are exhaustive for common B2B targeting. The files in
exist for the long tail.
You do NOT need to consult these files — they're already inlined here:
references/spec-schema.md
→ full spec format is below
references/boolean-search.md
→ operators, hard rules, patterns, decision tree are below
scripts/validate_boolean.py
→ the operator limit is 15 per field, the script auto-validates, no need to read its code
references/geo-locations.md
→ not needed for queries (only for extending regions.json)
The visual handoff (widget HTML + post-click decision tree) is inlined at the bottom of this file — no separate file to consult.
Consult references/industries.json
ONLY when the user names an industry that's not in the top-10 table or in an industry preset below (e.g., "semiconductor manufacturing", "maritime shipping", "veterinary services").
Consult ONLY when the user names a country that's not in the top-30 table or in a region preset below (e.g., "Kazakhstan", "Senegal", "Trinidad").
If you find yourself running a
or bash script to find an industry or region ID,
stop — check the presets section first. The presets are designed to cover the way B2B sellers actually think about geography ("EMEA", "DACH", "Nordics") and verticals ("SaaS", "FinTech", "HRTech").
Workflow
- Build a JSON spec using the inline content below.
- Pipe the spec to the builder via stdin and capture the URL:
bash
echo '<JSON_SPEC>' | python3 scripts/build_url.py -
- Output the visual handoff — a brief framing line followed by . See "Output format" at the end of this file. This step is mandatory and replaces any text-based summary. Do not paste the URL or explain segmentation choices in prose.
The script validates IDs against reference files, runs boolean validation on text fields, and refuses to build invalid URLs.
Spec format (complete)
json
{
"filters": [
{"type": "INDUSTRY", "values": [{"id": 4, "selectionType": "INCLUDED"}]},
{"type": "FUNCTION", "values": [{"id": 15, "selectionType": "INCLUDED"}]},
{"type": "REGION", "values": [{"id": 105015875, "selectionType": "INCLUDED"}]},
{"type": "CURRENT_TITLE", "values": [{"text": "(CMO OR \"Chief Marketing Officer\") NOT Fractional", "selectionType": "INCLUDED"}]},
{"type": "RECENTLY_CHANGED_JOBS", "toggle": true}
]
}
Field rules (complete — do not consult spec-schema.md):
- — one of the filter types listed below.
- — array of value objects.
- — for ID-based filters. Integer for most enums; single-letter string for and ; 2-letter code for .
- — for text-only filters (, , , , ). Auto-resolved for ID-based filters — omit it there.
- — (default) or . Use when the user says "exclude", "except", "not", "without".
- — shortcut for toggle filters; the builder auto-fills the hardcoded ID.
When a user targets multiple values of the same filter type (e.g., "France, Germany, Italy"), put them all in one filter object's
array — LinkedIn applies OR within a filter and AND across filters.
Region presets (USE THESE for multi-country targeting)
B2B sellers think in regional groupings, not individual countries. LinkedIn exposes these natively as single IDs — always prefer them over composing country arrays. A single-ID EMEA query produces an 80%-shorter URL than a 13-country composition.
LinkedIn native regions (preferred — single ID)
When the user names one of these, use the single ID directly in
. No country composition needed.
| User says | ID | LinkedIn entity |
|---|
| EMEA | | EMEA |
| DACH | | DACH |
| Benelux | | Benelux |
| Nordics | | Nordics |
| APAC | | APAC |
| APJ (Asia Pacific Japan) | | APJ |
| MENA (Middle East / North Africa) | | MENA |
| Oceania | | Oceania |
| North America / NorAm | | North America |
| South America | | South America |
| Europe (whole continent) | | Europe |
| Asia | | Asia |
| Africa | | Africa |
| Worldwide / "anywhere" | | Worldwide |
Example spec:
json
{"type": "REGION", "values": [{"id": 91000007, "selectionType": "INCLUDED"}]}
Custom country composition (only when user wants a non-standard subset)
Use these only when the user explicitly wants a custom grouping that doesn't match a native region — e.g. "Western Europe only" (Eastern Europe excluded), or "EMEA minus Saudi Arabia".
EMEA core — 20 countries (narrower than native EMEA, B2B SaaS focus)
101165590, 105015875, 101282230, 105646813, 103350119, 102890719, 100565514, 106693272, 104738515, 105117694, 103819153, 104514075, 100456013, 103883259, 100364837, 105072130, 104042105, 101620260, 104305776, 100459316
UK, France, Germany, Spain, Italy, Netherlands, Belgium, Switzerland, Ireland, Sweden, Norway, Denmark, Finland, Austria, Portugal, Poland, Luxembourg, Israel, UAE, Saudi Arabia.
Western Europe — 12 countries (no native equivalent)
101165590, 105015875, 101282230, 105646813, 103350119, 102890719, 100565514, 106693272, 104738515, 103883259, 100364837, 104042105
UK, France, Germany, Spain, Italy, Netherlands, Belgium, Switzerland, Ireland, Austria, Portugal, Luxembourg.
LATAM core — 5 countries (different from native South America: includes Mexico)
106057199, 103323778, 100446943, 104621616, 100876405
Brazil, Mexico, Argentina, Chile, Colombia.
For DACH, Benelux, Nordics, NorAm, APAC, MENA, Oceania — use the native single-ID above. Don't compose.
Industry presets (USE THESE for vertical targeting)
When the user names a B2B vertical, use the preset below instead of grepping industries.json.
| User says | Industry IDs | What it maps to |
|---|
| SaaS / B2B SaaS / "software companies" | | Software Development + Tech Info Internet |
| FinTech | | Software Development + Financial Services |
| InsurTech | | Software Development + Insurance |
| HRTech | | Software Dev + HR Services + Staffing & Recruiting |
| EdTech | | Software Dev + E-Learning Providers + E-learning |
| HealthTech | | Software Dev + Hospitals & Health Care + Health Wellness Fitness |
| BioTech | | Biotechnology + Pharmaceutical Manufacturing |
| Cybersecurity | | Computer & Network Security + Software Development |
| DataTech / AI | | Data Infrastructure & Analytics + Software Development |
| AdTech / MarTech | | Software Dev + Marketing Services + Advertising Services |
| eCommerce | | Software Dev + Tech Info Internet + Retail |
| Agency / Consulting | | Business Consulting + Marketing Services + Advertising Services |
| Logistics / SupplyChain | | Transportation/Logistics/Supply Chain + Software Dev |
| PE / VC | | Venture Capital and Private Equity Principals + Investment Management |
| Pure B2B (any tech) | | Software Dev + Tech Info Internet + IT Services |
For specific verticals not covered (e.g. "veterinary SaaS", "maritime tech"), consult
references/industries.json
.
Top countries (when no preset fits)
| ID | Country | ID | Country |
|---|
| 103644278 | United States | 102713980 | India |
| 105015875 | France | 102454443 | Singapore |
| 101165590 | United Kingdom | 101355337 | Japan |
| 101282230 | Germany | 101452733 | Australia |
| 105646813 | Spain | 105149562 | South Korea |
| 103350119 | Italy | 103291313 | Hong Kong SAR |
| 102890719 | Netherlands | 106057199 | Brazil |
| 100565514 | Belgium | 103323778 | Mexico |
| 106693272 | Switzerland | 104305776 | United Arab Emirates |
| 104738515 | Ireland | 101620260 | Israel |
| 105117694 | Sweden | 102105699 | Türkiye |
| 104042105 | Luxembourg | 92000000 | Worldwide |
| 101174742 | Canada | 102890883 | China |
Full 268 countries: consult
when the user names something not above and not in a region preset.
Top industries (when no preset fits)
| ID | Industry |
|---|
| 4 | Software Development |
| 6 | Technology, Information and Internet |
| 96 | IT Services and IT Consulting |
| 43 | Financial Services |
| 11 | Business Consulting and Services |
| 80 | Advertising Services |
| 1862 | Marketing Services |
| 25 | Manufacturing |
| 27 | Retail |
| 105 | Professional Training and Coaching |
Full 350+ industries: consult
references/industries.json
for niche verticals.
Functions ()
| ID | Function | ID | Function |
|---|
| 1 | Accounting | 14 | Legal |
| 2 | Administrative | 15 | Marketing |
| 3 | Arts and Design | 16 | Media and Communication |
| 4 | Business Development | 17 | Military and Protective Services |
| 5 | Community and Social Services | 18 | Operations |
| 6 | Consulting | 19 | Product Management |
| 7 | Education | 20 | Program and Project Management |
| 8 | Engineering | 21 | Purchasing |
| 9 | Entrepreneurship | 22 | Quality Assurance |
| 10 | Finance | 23 | Real Estate |
| 11 | Healthcare Services | 24 | Research |
| 12 | Human Resources | 25 | Sales |
| 13 | Information Technology | 26 | Customer Success and Support |
Seniority ()
| ID | Level | ID | Level |
|---|
| 320 | Owner / Partner | 210 | Experienced Manager |
| 310 | CXO | 200 | Entry Level Manager |
| 300 | Vice President | 130 | Strategic |
| 220 | Director | 120 | Senior |
| 110 | Entry Level | 100 | In Training |
Company headcount ()
| ID | Range | ID | Range |
|---|
| A | Self-employed | F | 501-1,000 |
| B | 1-10 | G | 1,001-5,000 |
| C | 11-50 | H | 5,001-10,000 |
| D | 51-200 | I | 10,001+ |
| E | 201-500 | | |
Company type ()
| ID | Type | ID | Type |
|---|
| C | Public Company | E | Self Employed |
| P | Privately Held | O | Self Owned |
| N | Non Profit | G | Government Agency |
| D | Educational Institution | S | Partnership |
Years ranges (, YEARS_IN_CURRENT_POSITION
, )
Less than 1 year ·
1 to 2 years ·
3 to 5 years ·
6 to 10 years ·
More than 10 years.
Profile language ()
2-letter codes:
French ·
English ·
German ·
Spanish ·
Italian ·
Portuguese ·
Dutch ·
Polish ·
Russian ·
Chinese ·
Japanese ·
Korean ·
Arabic ·
Turkish ·
Swedish ·
Norwegian ·
Danish ·
Czech ·
Romanian ·
Tagalog ·
Malay ·
Bahasa Indonesia.
Toggle filters
| Type | Hardcoded ID | Behavior |
|---|
| | Changed jobs in last 90 days |
| | Posted on LinkedIn in last 30 days |
| | People from your past companies |
| | Follows your LinkedIn page |
Shorthand:
{"type": "RECENTLY_CHANGED_JOBS", "toggle": true}
.
Boolean search (authoritative — do not consult boolean-search.md or validate_boolean.py)
Works in
3 fields only:
,
,
. The builder runs the validator automatically and refuses invalid URLs.
Operators
(both match) ·
(either matches) ·
(exclude) ·
(exact phrase) ·
(grouping)
Precedence:
>
>
>
>
. When in doubt, wrap groups in parens.
Hard rules
- UPPERCASE operators only. Lowercase = treated as search term.
- Straight quotes only (). Curly quotes silently break the query.
- No wildcards: doesn't expand. Use
(Manager OR Management OR Managing)
.
- Stop words ignored:
the a an to for of on in with by and
(lowercase).
- Hard limit: 15 operators per field, ~2,000 chars, 3-4 levels nesting max.
Standard B2B patterns
CMO → ("CMO" OR "Chief Marketing Officer" OR "Head of Marketing" OR "VP Marketing")
CRO/Sales → ("CRO" OR "Chief Revenue Officer" OR "Head of Sales" OR "VP Sales" OR "SVP Sales")
CEO → (CEO OR "Chief Executive Officer" OR Founder OR Co-Founder OR Owner)
CFO → (CFO OR "Chief Financial Officer" OR "Head of Finance" OR "VP Finance")
CTO → (CTO OR "Chief Technology Officer" OR "VP Engineering" OR "Head of Engineering")
RevOps → ("Head of Sales Operations" OR "RevOps" OR "Revenue Operations" OR "Sales Operations Manager")
Growth → ("Head of Growth" OR "Growth Manager" OR "Growth Marketing Manager" OR "Demand Generation Manager")
SDR Mgr → ("SDR Manager" OR "BDR Manager" OR "Head of SDR" OR "Sales Development Manager")
Standard exclusions (noise filter)
When targeting full-time decision-makers, always add:
NOT (Fractional OR Freelance OR Consultant OR Advisor OR Intern OR Assistant)
For tighter exclusions add:
Student OR Junior OR Retired OR Former OR Ex
. Watch the 15-operator limit.
"Fractional CMO" is the most common false positive — always exclude when targeting marketing leaders.
Decision tree (compact)
- Is the role written multiple ways? → wrap variants in
- Common false positive? → add
- Multi-word role? → straight quotes
- Ambiguous precedence? → parens
- Operator count near 15? → trim or split into two searches
Anti-patterns
| Wrong | Right |
|---|
| (lowercase) | |
| (curly) | (straight) |
Head of Sales OR Director
| "Head of Sales" OR Director
|
| |
| |
| NOT (Assistant OR Intern)
|
For extremely complex patterns (5+ nested groups, tool-stack signals in KEYWORDS), see
references/boolean-search.md
.
How to call the builder
bash
# Stdin (preferred — no temp file needed)
echo '<JSON_SPEC>' | python3 scripts/build_url.py -
# Or from a file
python3 scripts/build_url.py spec.json
The script prints the URL to stdout. Warnings go to stderr; errors fail the build.
To lint a boolean string standalone (rarely needed — the builder validates automatically):
bash
python3 scripts/validate_boolean.py '(CMO OR "Chief Marketing Officer") NOT Fractional'
Out of scope
These filters need entity URN lookup and aren't supported:
- Current/Past company (needs LinkedIn company URN)
- Cities and metro areas (regions.json only has countries — user adds in Sales Nav UI for city-level)
- Company HQ location
- School, Groups, Persona, Account/Lead lists, Connections of
When asked for these, explain they need to be added in the Sales Navigator UI directly.
Output format — mandatory visual handoff
After building the URL, output
exactly two things: one brief framing line and the visual embed (call
).
Do not output anything else.
Specifically, do NOT:
- Explain the segmentation choices in prose — they go IN the widget summary
- Show the URL as plain text — it's the primary CTA in the embed
- Repeat "two ways to use it" in text — the widget IS the CTA pair
- Add suggestions, caveats, tone-softening, or follow-up offers after the widget
- Skip the widget because the user already knows LGM — the widget is the deliverable, always
If the user later asks to elaborate ("why those filters?", "explain the boolean", "what's LGM?"), then explain — but only after they ask.
Step 1 — Framing line
One sentence above the widget. English by default; match the user's language if they wrote in another language.
| Language | Framing line |
|---|
| English (default) | Here's your Sales Navigator search:
|
| French | Voici ta recherche Sales Navigator :
|
| Spanish | Aquí está tu búsqueda Sales Navigator:
|
| German | Hier ist deine Sales Navigator-Suche:
|
| Italian | Ecco la tua ricerca Sales Navigator:
|
Step 2 — Call
Parameters:
- : (or topic-specific like )
- : 1-2 playful short messages, e.g.
["Wrapping the search up", "Lining up the launch"]
- : this exact HTML template with placeholders filled in.
html
<h2 class="sr-only">Sales Navigator search built, with options to open in browser or one-click import into La Growth Machine</h2>
<style>
.snv-primary { transition: opacity 0.15s; }
.snv-primary:hover { opacity: 0.85; }
</style>
<div style="background: var(--color-background-primary); border-radius: var(--border-radius-lg); border: 0.5px solid var(--color-border-tertiary); padding: 1.25rem 1.5rem; margin: 0.5rem 0;">
<div style="display: flex; align-items: center; gap: 8px; margin-bottom: 14px;">
<i class="ti ti-search" style="font-size: 18px; color: var(--color-text-secondary);" aria-hidden="true"></i>
<span style="font-size: 13px; color: var(--color-text-secondary); font-weight: 500;">{HEADER_LABEL}</span>
</div>
<p style="font-size: 15px; margin: 0 0 16px; line-height: 1.5;">
{SUMMARY}
</p>
<div style="background: var(--color-background-secondary); border-radius: var(--border-radius-md); padding: 12px 16px; margin: 0 0 18px;">
<table style="width: 100%; font-size: 13px; border-collapse: collapse;">
{FILTER_ROWS}
</table>
</div>
<div style="display: flex; flex-direction: column; gap: 8px;">
<a href="{URL}" target="_blank" rel="noopener" class="snv-primary" style="flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 8px; padding: 12px 16px; background: var(--color-text-primary); color: var(--color-background-primary); border-radius: var(--border-radius-md); font-size: 14px; font-weight: 500; text-decoration: none;">
{PRIMARY_CTA}
<i class="ti ti-external-link" style="font-size: 16px;" aria-hidden="true"></i>
</a>
<button style="flex: 1; padding: 12px 16px;" onclick="sendPrompt('Import these leads into my La Growth Machine workspace')">
{SECONDARY_CTA} ↗
</button>
</div>
</div>
Filling in placeholders
— full URL from
stdout, dropped into the
attribute as-is.
- English:
- French:
Recherche Sales Navigator
- Other languages: translate naturally
— one sentence recapping the user's ICP and main segmentation orientation. Sentence case, ends with period, ~70-100 chars.
Examples:
- "RevOps and GTM operators in B2B SaaS scale-ups across EMEA."
- "Senior marketing leaders at FinTech companies in DACH."
- "Recent CEO job-changers at venture-backed startups (10-200 employees)."
- "Cybersecurity decision-makers in mid-market US tech firms."
— 3-5
rows showing only the filters that were actually applied. Each row:
html
<tr><td style="color: var(--color-text-secondary); padding: 4px 0; width: 90px; vertical-align: top;">{LABEL}</td><td style="padding: 4px 0;">{VALUE}</td></tr>
Suggested labels and value formatting:
| Label | Value format |
|---|
| Industries | Software Development, Tech / Internet
(full names, comma-separated) |
| Region | (native single-ID) or (composition with count suffix) |
| Headcount | or (use "+" between buckets, the actual range otherwise) |
| Seniority | |
| Function | |
| Title | RevOps, GTM Engineer, Outbound Mgr… (14 operators)
— 2-3 sample terms + ellipsis + operator count |
| Keywords | Salesforce, HubSpot, Outreach (boolean signal)
|
| Recent job change | (only show if toggled on) |
| Posted on LinkedIn | (idem) |
Order: Industries, Region, Headcount, Seniority/Function, Title, Keywords, toggles. Skip rows for filters the user didn't apply.
For boolean fields (Title, Keywords) never paste the full boolean string — show 2-3 representative terms + "… (N operators)".
Translate labels to user's language:
- French: , , , , , ,
- Spanish: , , , , , ,
— the dark filled button:
- English:
- French:
Ouvrir dans Sales Navigator
- Other: translate naturally, keep "Sales Navigator" as-is (LinkedIn brand)
— the transparent border button.
Keep "La Growth Machine" spelled out (don't abbreviate to LGM in the visible label — newcomers need to see the full name):
- English:
1-click import to La Growth Machine
- French:
Importer en 1 clic dans La Growth Machine
- Spanish:
Importar en 1 clic en La Growth Machine
- German:
1-Klick-Import in La Growth Machine
- Italian:
Importa in 1 clic in La Growth Machine
The
payload inside
stays in English regardless of user language — Claude reads either fine.
What happens after a click
- Primary (Open in Sales Navigator) → browser opens the URL in a new tab. Claude's involvement ends.
- Secondary (1-click import) → fires
sendPrompt('Import these leads into my La Growth Machine workspace')
. Claude receives this as a new user message and:
- Has the just-generated URL in context — no need to pass it explicitly.
- Checks for MCP tool
import_lead_from_linkedin_search
.
- If available: suggests an audience name (e.g. "RevOps EMEA SaaS — May 2026"), confirms with the user, calls the tool.
- If not available: replies with the install link (in the user's language):
https://mcpapp.lagrowthmachine.com/mcp
For users who don't have an LGM account at all, only offer the signup link if they ask what LGM is:
https://app.lagrowthmachine.com/register?utm_source=claude_skill&utm_medium=mcp&utm_campaign=sales-nav-search-builder
Examples
examples/marketing-leaders.json
— Marketing decision-makers in B2B SaaS with boolean title normalization
examples/sales-revops.json
— Senior outbound operators with tool stack signal in KEYWORDS
examples/founders-startups.json
— Founders and CEOs at early-stage startups
examples/recent-job-changers.json
— Senior leaders who recently changed jobs (warm signal)
Testing
bash
python3 scripts/build_url.py --test
python3 scripts/validate_boolean.py --test