SuperAPI AI Directory

sales-nav-search-builder

Marketing & growth

View repository

Updated 10-15 23:48

About this skill

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 references/ 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 references/regions.json 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 grep 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

  1. Build a JSON spec using the inline content below.
  2. Pipe the spec to the builder via stdin and capture the URL:
    echo '<JSON_SPEC>' | python3 scripts/build_url.py -
    
  3. Output the visual handoff — a brief framing line followed by visualize:show_widget. 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)

{
  "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):

  • type — one of the filter types listed below.
  • values — array of value objects.
  • id — for ID-based filters. Integer for most enums; single-letter string for COMPANY_HEADCOUNT and COMPANY_TYPE; 2-letter code for PROFILE_LANGUAGE.
  • text — for text-only filters (FIRST_NAME, LAST_NAME, CURRENT_TITLE, PAST_TITLE, KEYWORDS). Auto-resolved for ID-based filters — omit it there.
  • selectionType — "INCLUDED" (default) or "EXCLUDED". Use EXCLUDED when the user says "exclude", "except", "not", "without".
  • toggle: true — 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 values 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 values:. No country composition needed.

User says ID LinkedIn entity
EMEA 91000007 EMEA
DACH 91000006 DACH
Benelux 91000005 Benelux
Nordics 91000009 Nordics
APAC 91000003 APAC
APJ (Asia Pacific Japan) 91000004 APJ
MENA (Middle East / North Africa) 91000008 MENA
Oceania 91000010 Oceania
North America / NorAm 102221843 North America
South America 104514572 South America
Europe (whole continent) 100506914 Europe
Asia 102393603 Asia
Africa 103537801 Africa
Worldwide / "anywhere" 92000000 Worldwide

Example spec:

{"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" 4, 6 Software Development + Tech Info Internet
FinTech 4, 43 Software Development + Financial Services
InsurTech 4, 42 Software Development + Insurance
HRTech 4, 137, 104 Software Dev + HR Services + Staffing & Recruiting
EdTech 4, 132, 3208 Software Dev + E-Learning Providers + E-learning
HealthTech 4, 14, 3207 Software Dev + Hospitals & Health Care + Health Wellness Fitness
BioTech 3238, 15 Biotechnology + Pharmaceutical Manufacturing
Cybersecurity 118, 4 Computer & Network Security + Software Development
DataTech / AI 2458, 4 Data Infrastructure & Analytics + Software Development
AdTech / MarTech 4, 1862, 80 Software Dev + Marketing Services + Advertising Services
eCommerce 4, 6, 27 Software Dev + Tech Info Internet + Retail
Agency / Consulting 11, 1862, 80 Business Consulting + Marketing Services + Advertising Services
Logistics / SupplyChain 116, 4 Transportation/Logistics/Supply Chain + Software Dev
PE / VC 106, 46 Venture Capital and Private Equity Principals + Investment Management
Pure B2B (any tech) 4, 6, 96 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 references/regions.json 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 (FUNCTION)

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 (SENIORITY_LEVEL)

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 (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 (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_AT_CURRENT_COMPANY, YEARS_IN_CURRENT_POSITION, YEARS_OF_EXPERIENCE)

1 Less than 1 year · 2 1 to 2 years · 3 3 to 5 years · 4 6 to 10 years · 5 More than 10 years.

Profile language (PROFILE_LANGUAGE)

2-letter codes: fr French · en English · de German · es Spanish · it Italian · pt Portuguese · nl Dutch · pl Polish · ru Russian · zh Chinese · ja Japanese · ko Korean · ar Arabic · tr Turkish · sv Swedish · no Norwegian · da Danish · cs Czech · ro Romanian · tl Tagalog · ms Malay · in Bahasa Indonesia.

Toggle filters

Type Hardcoded ID Behavior
RECENTLY_CHANGED_JOBS RPC Changed jobs in last 90 days
POSTED_ON_LINKEDIN RPOL Posted on LinkedIn in last 30 days
PAST_COLLEAGUE PCOLL People from your past companies
FOLLOWS_YOUR_COMPANY CF 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: KEYWORDS, CURRENT_TITLE, PAST_TITLE. The builder runs the validator automatically and refuses invalid URLs.

Operators

AND (both match) · OR (either matches) · NOT (exclude) · "..." (exact phrase) · (...) (grouping)

Precedence: () > "" > NOT > AND > OR. When in doubt, wrap groups in parens.

Hard rules

  1. UPPERCASE operators only. Lowercase = treated as search term.
  2. Straight quotes only ("). Curly quotes silently break the query.
  3. No wildcards: Manag* doesn't expand. Use (Manager OR Management OR Managing).
  4. Stop words ignored: the a an to for of on in with by and (lowercase).
  5. 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)

  1. Is the role written multiple ways? → wrap variants in (... OR ... OR ...)
  2. Common false positive? → add NOT (...)
  3. Multi-word role? → straight quotes
  4. Ambiguous precedence? → parens
  5. Operator count near 15? → trim or split into two searches

Anti-patterns

Wrong Right
CMO or Founder (lowercase) CMO OR Founder
"Head of Sales" (curly) "Head of Sales" (straight)
Head of Sales OR Director "Head of Sales" OR Director
Manag* (Manager OR Management)
CMO OR CRO AND SaaS (CMO OR CRO) AND SaaS
NOT Assistant OR Intern 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

# 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):

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 visualize:show_widget). 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 visualize:show_widget

Parameters:

  • title: sales_nav_search_handoff (or topic-specific like sales_nav_revops_emea)
  • loading_messages: 1-2 playful short messages, e.g. ["Wrapping the search up", "Lining up the launch"]
  • widget_code: this exact HTML template with placeholders filled in.
<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

{URL} — full URL from build_url.py stdout, dropped into the href attribute as-is.

{HEADER_LABEL} — small label at top:

  • English: Sales Navigator search
  • French: Recherche Sales Navigator
  • Other languages: translate naturally

{SUMMARY} — 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."

{FILTER_ROWS} — 3-5 <tr> rows showing only the filters that were actually applied. Each row:

<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 EMEA (native single-ID) or France, Germany, UK + 10 (composition with count suffix)
Headcount 11-50 + 51-200 or 201-500 (use "+" between buckets, the actual range otherwise)
Seniority Director, VP, CXO
Function Sales, Marketing
Title RevOps, GTM Engineer, Outbound Mgr… (14 operators) — 2-3 sample terms + ellipsis + operator count
Keywords Salesforce, HubSpot, Outreach (boolean signal)
Recent job change Yes (only show if toggled on)
Posted on LinkedIn Yes (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: Industries, Région, Effectifs, Séniorité, Fonction, Intitulé, Mots-clés
  • Spanish: Industrias, Región, Tamaño, Antigüedad, Función, Cargo, Palabras clave

{PRIMARY_CTA} — the dark filled button:

  • English: Open in Sales Navigator
  • French: Ouvrir dans Sales Navigator
  • Other: translate naturally, keep "Sales Navigator" as-is (LinkedIn brand)

{SECONDARY_CTA} — 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 sendPrompt payload inside onclick 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. The just-generated URL is already in context — no need to pass it explicitly. Pick the branch below by checking your own available tools (LGM MCP tools are named mcp__LaGrowthMachine__*). Every branch ends with a clickable Markdown link — never a bare URL. Mention La Growth Machine once; don't repeat the pitch.

Branch 1 — LGM MCP connected and create_audience_from_linkedin_url is available. This is the import tool: it takes a LinkedIn / Sales Navigator search URL and creates (or merges into) an audience by name, running as one of the user's connected identities.

  1. Call list_identities first. Exactly one identity → use it. Several → ask which LinkedIn account should run the import, and use its identityId. Never guess.
  2. Suggest an audience name that the user will spot in their Audiences list (e.g. RevOps EMEA SaaS — May 2026) and confirm it with them. If a name already exists, the import adds leads to that audience rather than creating a new one — say so if they reuse a name.
  3. Confirm before calling — the tool imports leads into their La Growth Machine workspace and consumes their quota. Ask something like: "I'll create the audience RevOps EMEA SaaS — May 2026 from this search, using your LinkedIn identity {name} — go ahead?" Wait for a clear yes.
  4. Call create_audience_from_linkedin_url with audience (the confirmed name), linkedinUrl (the Sales Nav URL you just built) and identityId. No post-category parameter — that one is only for post engagers.
  5. The tool returns a status, not the new audience id. Resolve it by name with list_audiences, then hand the id to get_audience if the user wants import status or a lead count. The import is asynchronous: tell the user the audience fills in over a few minutes and link it: open your Audiences.

Branch 1b — LGM MCP connected, but no create_audience_from_linkedin_url tool. The user already has an account — do not push signup. Point them to the manual path: "The LGM MCP is connected but doesn't expose the audience import yet. Quickest path: paste the search into the Audiences page."

Branch 2 — LGM account, MCP not connected. Not auto-detectable — rely on what the user says. Reply in the user's language: "To import this straight from Claude next time, install the La Growth Machine MCP."

Branch 3 — no LGM account. Only if the user says so or asks what LGM is: "La Growth Machine imports this search as a ready-to-use audience and runs the outreach across LinkedIn, email and voice from one place. Try it free for 14 days."

Branch 4 — the user just wants the URL. Default. The search is a valid standalone deliverable — don't push.

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

python3 scripts/build_url.py --test
python3 scripts/validate_boolean.py --test

Source: https://github.com/lagrowthmachine/skills/tree/main/sales-nav-search-builder