> **Building with AI coding agents?** If you're using an AI coding agent, install the official Scalekit plugin. It gives your agent full awareness of the Scalekit API — reducing hallucinations and enabling faster, more accurate code generation.
>
> - **Claude Code**: `claude plugin marketplace add scalekit-inc/claude-code-authstack && claude plugin install <auth-type>@scalekit-auth-stack`
> - **GitHub Copilot CLI**: `copilot plugin marketplace add scalekit-inc/github-copilot-authstack` then `copilot plugin install <auth-type>@scalekit-auth-stack`
> - **Codex**: run the bash installer, restart, then open Plugin Directory and enable `<auth-type>`
> - **Skills CLI** (Windsurf, Cline, 40+ agents): `npx skills add scalekit-inc/skills --list` then `--skill <skill-name>`
>
> `<auth-type>` / `<skill-name>`: `agentkit`, `full-stack-auth`, `mcp-auth`, `modular-sso`, `modular-scim` — [Full setup guide](https://docs.scalekit.com/dev-kit/build-with-ai/)

---

# LeadIQ connector

Connect to LeadIQ to search and enrich B2B contacts and companies with verified emails, direct dials, and mobile numbers. Build prospect lists and power...

**Authentication:** API Key
**Categories:** CRM & Sales, Analytics
1. ### Install the SDK

   
     ### Node.js

```bash frame="terminal"
npm install @scalekit-sdk/node
```

     ### Python

```bash frame="terminal"
pip install scalekit
```

   

   Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/)

2. ### Set your credentials

   Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**.

```sh showLineNumbers=false title=".env"
SCALEKIT_ENVIRONMENT_URL=<your-environment-url>
SCALEKIT_CLIENT_ID=<your-client-id>
SCALEKIT_CLIENT_SECRET=<your-client-secret>
```

3. ### Set up the connector

   Register your LeadIQ credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment.

   ## Dashboard setup steps

Register your LeadIQ API key with Scalekit so it stores it securely and injects it into every request. LeadIQ uses API key authentication — there is no redirect URI or OAuth flow.

1. ### Get your LeadIQ API key

   - Sign in to [LeadIQ](https://app.leadiq.com) and go to **Settings** → **API Keys**.
   - Copy the **Secret API key** value, or click **Generate new API key** to create one dedicated to this integration.

   > Image: LeadIQ Settings API Keys page showing Secret API key and Secret Base64 API key fields

   > tip: Store the key securely
>
> LeadIQ API keys have full account access. Store the key in a secrets manager and never hard-code it in your application source code.

2. ### Create a connection in Scalekit

   - In [Scalekit dashboard](https://app.scalekit.com), go to **AgentKit** → **Connections** → **Create Connection**. Find **LeadIQ** and click **Create**.
   - Note the **Connection name** — you will use this as `connection_name` in your code (e.g., `leadiq`).
   - Click **Save**.

3. ### Add a connected account

   Connected accounts link a specific user identifier in your system to their LeadIQ API key. Add them via the dashboard for testing, or via the Scalekit API in production.

   **Via dashboard (for testing)**

   - Open the connection you created and click the **Connected Accounts** tab → **Add account**.
   - Fill in:
     - **Your User's ID** — a unique identifier for this user in your system (e.g., `user_123`)
     - **API Key** — the LeadIQ API key from step 1
   - Click **Create Account**.

   **Via API (for production)**

   
     ### Node.js

```typescript

const scalekit = new Scalekit(
  process.env.SCALEKIT_ENV_URL,
  process.env.SCALEKIT_CLIENT_ID,
  process.env.SCALEKIT_CLIENT_SECRET,
);

// Never hard-code credentials — read from secure storage or user input
const leadiqApiKey = getUserLeadIQApiKey(); // retrieve from your secure store

await scalekit.actions.upsertConnectedAccount({
  connectionName: 'leadiq',
  identifier: 'user_123',
  credentials: {
    username: leadiqApiKey,
  },
});
```

     ### Python

```python

from scalekit import ScalekitClient

scalekit_client = ScalekitClient(
    env_url=os.environ["SCALEKIT_ENV_URL"],
    client_id=os.environ["SCALEKIT_CLIENT_ID"],
    client_secret=os.environ["SCALEKIT_CLIENT_SECRET"],
)

# Never hard-code credentials — read from secure storage or user input
leadiq_api_key = get_user_leadiq_api_key()  # retrieve from your secure store

scalekit_client.actions.upsert_connected_account(
    connection_name="leadiq",
    identifier="user_123",
    credentials={"username": leadiq_api_key},
)
```

   

   > tip: Production usage tip
>
> In production, call `upsert_connected_account` (Python) / `upsertConnectedAccount` (Node.js) when a user connects their LeadIQ account — for example, on an integrations settings page in your app.

## What you can do

Connect this agent connector to let your agent:

- **Search contacts** — look up verified work emails, direct dials, and mobile numbers by LinkedIn URL, email, or name
- **Preview before consuming credits** — check whether LeadIQ has a work email or phone for a person without spending credits
- **Enrich companies** — fetch firmographics including industry, employee count, and location by domain or name
- **Advanced prospecting** — filter contacts by title, seniority, industry, company size, and location; get results flat or grouped by company
- **Manage prospect lists** — create lists, add contacts, and retrieve saved prospects (requires Prospector plan)
- **Monitor quota** — check API credit usage, plan limits, and subscription status before making credit-consuming calls

## Common workflows

export const sectionTitle = 'Common workflows'

> tip: No OAuth flow needed
>
> LeadIQ uses API key auth — there is no authorization link or redirect flow. Once you call `upsertConnectedAccount` (Node.js) / `upsert_connected_account` (Python) with your API key, your users can make requests immediately.

## Check credit quota before searching

Always check available credits before calling tools that consume them (`leadiq_search_people`, `leadiq_flat_advanced_search`, `leadiq_grouped_advanced_search`).

  ### Node.js

```typescript
const usage = await actions.executeTool({
  toolName: 'leadiq_get_usage',
  connectionName: 'leadiq',
  identifier: 'user_123',
  toolInput: {},
});
console.log(usage.data?.usage);
```

  ### Python

```python
usage = actions.execute_tool(
    tool_name="leadiq_get_usage",
    connection_name="leadiq",
    identifier="user_123",
    tool_input={},
)
print(usage.data)
```

## Preview contact availability before consuming credits

Use `leadiq_search_people_preview` to check whether LeadIQ has a work email or phone for a person before calling `leadiq_search_people`. The preview call does not consume credits.

  ### Node.js

```typescript
const preview = await actions.executeTool({
  toolName: 'leadiq_search_people_preview',
  connectionName: 'leadiq',
  identifier: 'user_123',
  toolInput: {
    linkedin_url: 'https://www.linkedin.com/in/janedoe',
  },
});

if (preview.data?.data?.searchPeoplePreview?.hasEmail) {
  // Safe to call leadiq_search_people — credits will be consumed
}
```

  ### Python

```python
preview = actions.execute_tool(
    tool_name="leadiq_search_people_preview",
    connection_name="leadiq",
    identifier="user_123",
    tool_input={"linkedin_url": "https://www.linkedin.com/in/janedoe"},
)

result = preview.data.get("data", {}).get("searchPeoplePreview", {})
if result.get("hasEmail"):
    # Safe to call leadiq_search_people — credits will be consumed
    pass
```

## Look up a contact by LinkedIn URL, email, or name

  ### Node.js

```typescript
// By LinkedIn URL (most precise)
const contact = await actions.executeTool({
  toolName: 'leadiq_search_people',
  connectionName: 'leadiq',
  identifier: 'user_123',
  toolInput: {
    linkedin_url: 'https://www.linkedin.com/in/janedoe',
    limit: 1,
  },
});

// By name + company
const byName = await actions.executeTool({
  toolName: 'leadiq_search_people',
  connectionName: 'leadiq',
  identifier: 'user_123',
  toolInput: {
    first_name: 'Jane',
    last_name: 'Doe',
    company_name: 'Acme Corp',
    limit: 5,
  },
});
```

  ### Python

```python
# By LinkedIn URL (most precise)
contact = actions.execute_tool(
    tool_name="leadiq_search_people",
    connection_name="leadiq",
    identifier="user_123",
    tool_input={
        "linkedin_url": "https://www.linkedin.com/in/janedoe",
        "limit": 1,
    },
)

# By name + company
by_name = actions.execute_tool(
    tool_name="leadiq_search_people",
    connection_name="leadiq",
    identifier="user_123",
    tool_input={
        "first_name": "Jane",
        "last_name": "Doe",
        "company_name": "Acme Corp",
        "limit": 5,
    },
)
```

## Enrich a company by domain or name

  ### Node.js

```typescript
const company = await actions.executeTool({
  toolName: 'leadiq_search_company',
  connectionName: 'leadiq',
  identifier: 'user_123',
  toolInput: {
    domain: 'acme.com',
  },
});
console.log(company.data?.data?.searchCompany);
```

  ### Python

```python
company = actions.execute_tool(
    tool_name="leadiq_search_company",
    connection_name="leadiq",
    identifier="user_123",
    tool_input={"domain": "acme.com"},
)
print(company.data)
```

## Advanced people search with industry and seniority filters

Pass filter objects as Python dicts or JavaScript objects — not JSON-encoded strings.

  ### Node.js

```typescript
const results = await actions.executeTool({
  toolName: 'leadiq_flat_advanced_search',
  connectionName: 'leadiq',
  identifier: 'user_123',
  toolInput: {
    company_filter: {
      industries: ['Software Development'],
      sizes: [{ min: 50, max: 500 }],
    },
    contact_filter: {
      seniorities: ['VP', 'Director'],
    },
    limit: 10,
  },
});
const people = results.data?.data?.flatAdvancedSearch?.people ?? [];
```

  ### Python

```python
results = actions.execute_tool(
    tool_name="leadiq_flat_advanced_search",
    connection_name="leadiq",
    identifier="user_123",
    tool_input={
        "company_filter": {
            "industries": ["Software Development"],
            "sizes": [{"min": 50, "max": 500}],
        },
        "contact_filter": {
            "seniorities": ["VP", "Director"],
        },
        "limit": 10,
    },
)
people = results.data.get("data", {}).get("flatAdvancedSearch", {}).get("people", [])
```

## Advanced search grouped by company (account-based prospecting)

Returns results organized by company, each with a list of matching contacts. Useful for account-based outreach.

  ### Node.js

```typescript
const grouped = await actions.executeTool({
  toolName: 'leadiq_grouped_advanced_search',
  connectionName: 'leadiq',
  identifier: 'user_123',
  toolInput: {
    company_filter: {
      industries: ['Financial Services'],
      sizes: [{ min: 200, max: 5000 }],
    },
    contact_filter: {
      seniorities: ['Executive', 'VP'],
    },
    limit: 5,            // number of companies
    limit_per_company: 3, // contacts per company
  },
});
const companies = grouped.data?.data?.groupedAdvancedSearch?.companies ?? [];
```

  ### Python

```python
grouped = actions.execute_tool(
    tool_name="leadiq_grouped_advanced_search",
    connection_name="leadiq",
    identifier="user_123",
    tool_input={
        "company_filter": {
            "industries": ["Financial Services"],
            "sizes": [{"min": 200, "max": 5000}],
        },
        "contact_filter": {
            "seniorities": ["Executive", "VP"],
        },
        "limit": 5,             # number of companies
        "limit_per_company": 3, # contacts per company
    },
)
companies = (
    grouped.data.get("data", {})
    .get("groupedAdvancedSearch", {})
    .get("companies", [])
)
```

## Report incorrect contact data

Help improve LeadIQ data quality by reporting bounced emails or wrong phone numbers.

  ### Node.js

```typescript
await actions.executeTool({
  toolName: 'leadiq_submit_person_feedback',
  connectionName: 'leadiq',
  identifier: 'user_123',
  toolInput: {
    value: 'jane.doe@acme.com',
    status: 'Invalid',
    type: 'WorkEmail',
    invalid_reason: 'EmailBounceCode550',
  },
});
```

  ### Python

```python
actions.execute_tool(
    tool_name="leadiq_submit_person_feedback",
    connection_name="leadiq",
    identifier="user_123",
    tool_input={
        "value": "jane.doe@acme.com",
        "status": "Invalid",
        "type": "WorkEmail",
        "invalid_reason": "EmailBounceCode550",
    },
)
```

> note: Prospect list tools require a paid plan
>
> The `leadiq_get_lists`, `leadiq_get_list`, `leadiq_create_list`, and `leadiq_add_prospect_to_list` tools require a LeadIQ Prospector plan. On Freemium accounts these tools return a 401 from the prospector service.

## Tool list

Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you're not sure which name to use, list the tools available for the current user first.

## Tool list

### `leadiq_add_prospect_to_list`

Add a contact to an existing LeadIQ prospect list. Provide first name, last name, and any known contact details. Use Get Prospect Lists to find the list ID.

Parameters:

- `first_name` (`string`, required): First name of the prospect
- `last_name` (`string`, required): Last name of the prospect
- `list_id` (`string`, required): ID of the prospect list to add the contact to
- `company` (`string`, optional): Current company name of the prospect
- `company_domain` (`string`, optional): Website domain of the prospect's company
- `company_industry` (`string`, optional): Industry of the prospect's company
- `linkedin_url` (`string`, optional): LinkedIn profile URL of the prospect
- `mobile_phone` (`string`, optional): Mobile phone number of the prospect
- `notes` (`string`, optional): Internal notes about this prospect
- `seniority` (`string`, optional): Seniority level of the prospect
- `title` (`string`, optional): Job title of the prospect
- `work_email` (`string`, optional): Work email address of the prospect
- `work_phone` (`string`, optional): Work phone number of the prospect

### `leadiq_create_list`

Create a new prospect list in LeadIQ to organize contacts for outreach campaigns. Returns the created list ID for use with Add Prospect to List.

Parameters:

- `name` (`string`, required): Name of the prospect list
- `description` (`string`, optional): Optional description of the prospect list

### `leadiq_flat_advanced_search`

Search across LeadIQ's full contact database using advanced filters for title, seniority, company, industry, location, and more. Returns a flat list of matching contacts. Consumes credits per result.

Parameters:

- `company_excluded_filter` (`object`, optional): Exclude contacts at companies matching these criteria
- `company_filter` (`object`, optional): Filter by company attributes including name, domain, industry, size, and location
- `contact_excluded_filter` (`object`, optional): Exclude contacts matching these criteria
- `contact_filter` (`object`, optional): Filter contacts by title, seniority, role, location, and more
- `limit` (`integer`, optional): Maximum number of contacts to return (default 10)
- `skip` (`integer`, optional): Number of results to skip for pagination (default 0)

### `leadiq_get_account`

Retrieve the current LeadIQ account details including active plans, product subscriptions, billing status, and credit usage (available and used). Use this to check remaining search credits before making enrichment calls.

### `leadiq_get_list`

Retrieve a specific prospect list by ID, including its contacts with name, title, company, email, and LinkedIn URL. Use Get Prospect Lists first to find the list ID.

Parameters:

- `id` (`string`, required): ID of the prospect list to retrieve
- `prospects_cursor` (`string`, optional): Pagination cursor from a previous response to get the next batch of prospects
- `prospects_limit` (`integer`, optional): Maximum number of prospects to return from the list (default 25)

### `leadiq_get_lists`

Retrieve all prospect lists in the LeadIQ account. Returns list metadata including name, status, and timestamps. Use the returned list IDs with Get Prospect List to fetch contacts.

Parameters:

- `cursor` (`string`, optional): Pagination cursor from a previous response's nextCursor field
- `limit` (`integer`, optional): Maximum number of lists to return per page

### `leadiq_get_prospect`

Retrieve a single prospect record by ID, including full contact details: emails, phones, LinkedIn, title, company, and location.

Parameters:

- `id` (`string`, required): ID of the prospect to retrieve

### `leadiq_get_usage`

Retrieve API credit usage for the current billing period — plan credit counts, usage caps, trial usage, and subscription status. Use this to monitor quota before making credit-consuming calls.

### `leadiq_grouped_advanced_search`

Search LeadIQ's contact database with advanced filters and get results grouped by company. Each result contains a company record with its top matching contacts. Useful for account-based prospecting. Consumes credits per contact returned.

Parameters:

- `company_excluded_filter` (`object`, optional): Exclude companies matching these criteria
- `company_filter` (`object`, optional): Filter by company name, domain, industry, size, location, and more
- `contact_excluded_filter` (`object`, optional): Exclude contacts matching these criteria
- `contact_filter` (`object`, optional): Filter contacts by title, seniority, role, location, and more
- `limit` (`integer`, optional): Maximum number of companies to return (default 10)
- `limit_per_company` (`integer`, optional): Maximum number of contacts to return per company (default 5)
- `skip` (`integer`, optional): Number of companies to skip for pagination (default 0)

### `leadiq_search_company`

Search for a company by name, domain, or LinkedIn URL. Returns firmographic data including employee count, industry, headquarters location, and funding information.

Parameters:

- `domain` (`string`, optional): Company website domain
- `linkedin_id` (`string`, optional): LinkedIn company numeric ID
- `linkedin_url` (`string`, optional): LinkedIn company page URL
- `name` (`string`, optional): Company name to search for
- `strict` (`boolean`, optional): Enable strict matching — only return exact name or domain matches

### `leadiq_search_people`

Search for a person by LinkedIn URL, email, or name + company. At least one of: linkedin_url, email, or first_name+last_name must be provided. Returns verified work emails, direct dials, and current job details. Consumes LeadIQ credits per result.

Parameters:

- `company_domain` (`string`, optional): Domain of the person's current company
- `company_name` (`string`, optional): Current company name of the person
- `contains_work_contact_info` (`boolean`, optional): Only return results that have at least one work email or work phone
- `email` (`string`, optional): Known email address of the person
- `first_name` (`string`, optional): First name of the person to search for
- `full_name` (`string`, optional): Full name of the person (alternative to first_name + last_name)
- `last_name` (`string`, optional): Last name of the person to search for
- `limit` (`integer`, optional): Maximum number of results to return (default 10, max 25)
- `linkedin_url` (`string`, optional): LinkedIn profile URL of the person
- `skip` (`integer`, optional): Number of results to skip for pagination (default 0)

### `leadiq_search_people_preview`

Check whether LeadIQ has a work email or phone number for a person without consuming credits. Use this before calling Search People to avoid wasting credits on contacts with no data.

Parameters:

- `company_domain` (`string`, optional): Domain of the person's current company
- `company_name` (`string`, optional): Current company name of the person
- `email` (`string`, optional): Known email address of the person
- `first_name` (`string`, optional): First name of the person
- `full_name` (`string`, optional): Full name of the person
- `last_name` (`string`, optional): Last name of the person
- `linkedin_url` (`string`, optional): LinkedIn profile URL of the person

### `leadiq_submit_person_feedback`

Report incorrect or outdated contact data back to LeadIQ to improve data quality. Mark an email or phone as correct or invalid, and optionally provide a correction or bounce reason.

Parameters:

- `value` (`string`, required): The contact info value being reported (email address or phone number)
- `company_domain` (`string`, optional): Company domain for additional context
- `company_name` (`string`, optional): Company name for additional context
- `invalid_reason` (`string`, optional): Specific bounce or invalidity reason code (for invalid emails)
- `linkedin_url` (`string`, optional): LinkedIn URL of the person the feedback is about
- `person_id` (`string`, optional): LeadIQ person ID associated with the contact info
- `status` (`string`, optional): Whether the contact info is correct or invalid
- `title` (`string`, optional): Job title of the person at the time the contact info was used
- `type` (`string`, optional): Type of contact information being reported


---

## More Scalekit documentation

| Resource | What it contains | When to use it |
|----------|-----------------|----------------|
| [/llms.txt](/llms.txt) | Structured index with routing hints per product area | Start here — find which documentation set covers your topic before loading full content |
| [/llms-full.txt](/llms-full.txt) | Complete documentation for all Scalekit products in one file | Use when you need exhaustive context across multiple products or when the topic spans several areas |
| [sitemap-0.xml](https://docs.scalekit.com/sitemap-0.xml) | Full URL list of every documentation page | Use to discover specific page URLs you can fetch for targeted, page-level answers |
