sales-nav-search-builder — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited sales-nav-search-builder (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
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.
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 belowreferences/boolean-search.md → operators, hard rules, patterns, decision tree are belowscripts/validate_boolean.py → the operator limit is 15 per field, the script auto-validates, no need to read its codereferences/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").
echo '<JSON_SPEC>' | python3 scripts/build_url.py -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.
{
"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.
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.
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"}]}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.
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.
| 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.
| 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.
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_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)| 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_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)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.
| 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}.
Works in 3 fields only: KEYWORDS, CURRENT_TITLE, PAST_TITLE. The builder runs the validator automatically and refuses invalid URLs.
AND (both match) · OR (either matches) · NOT (exclude) · "..." (exact phrase) · (...) (grouping)
Precedence: () > "" > NOT > AND > OR. When in doubt, wrap groups in parens.
"). Curly quotes silently break the query.Manag* doesn't expand. Use (Manager OR Management OR Managing).the a an to for of on in with by and (lowercase).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")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.
(... OR ... OR ...)NOT (...)| 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.
# Stdin (preferred — no temp file needed)
echo '<JSON_SPEC>' | python3 scripts/build_url.py -
# Or from a file
python3 scripts/build_url.py spec.jsonThe 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'These filters need entity URN lookup and aren't supported:
When asked for these, explain they need to be added in the Sales Navigator UI directly.
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:
If the user later asks to elaborate ("why those filters?", "explain the boolean", "what's LGM?"), then explain — but only after they ask.
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: |
visualize:show_widgetParameters:
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>`{URL}` — full URL from build_url.py stdout, dropped into the href attribute as-is.
`{HEADER_LABEL}` — small label at top:
Sales Navigator searchRecherche Sales Navigator`{SUMMARY}` — one sentence recapping the user's ICP and main segmentation orientation. Sentence case, ends with period, ~70-100 chars.
Examples:
`{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:
Industries, Région, Effectifs, Séniorité, Fonction, Intitulé, Mots-clésIndustrias, Región, Tamaño, Antigüedad, Función, Cargo, Palabras clave`{PRIMARY_CTA}` — the dark filled button:
Open in Sales NavigatorOuvrir dans Sales Navigator`{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):
1-click import to La Growth MachineImporter en 1 clic dans La Growth MachineImportar en 1 clic en La Growth Machine1-Klick-Import in La Growth MachineImporta in 1 clic in La Growth MachineThe sendPrompt payload inside onclick stays in English regardless of user language — Claude reads either fine.
sendPrompt('Import these leads into my La Growth Machine workspace'). Claude receives this as a new user message and:import_lead_from_linkedin_search.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/marketing-leaders.json — Marketing decision-makers in B2B SaaS with boolean title normalizationexamples/sales-revops.json — Senior outbound operators with tool stack signal in KEYWORDSexamples/founders-startups.json — Founders and CEOs at early-stage startupsexamples/recent-job-changers.json — Senior leaders who recently changed jobs (warm signal)python3 scripts/build_url.py --test
python3 scripts/validate_boolean.py --testSource: https://github.com/lagrowthmachine/skills/tree/main/sales-nav-search-builder
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.