Skip to content
Scalekit Docs
Talk to an Engineer Dashboard

HeyReach

API Key outreachlinkedinsalescrm

HeyReach

Connect this agent connector to let your agent:

  • Add leads to a campaign — Enroll up to 100 leads in an active campaign, bound to LinkedIn sender accounts
  • Verify the API key — Confirm the stored key is valid before running other tools
  • List campaigns — Page through outreach campaigns, statuses, and sender account IDs
  • List LinkedIn sender accounts — Discover connected profiles used to send outreach
  • List lead lists — Find list IDs for bulk lead retrieval
  • Get campaign details — Load one campaign’s status, stats, lists, and sender accounts
  • Monitor inbox conversations — Filter and page LinkedIn replies across accounts and campaigns
  • Look up a lead — Fetch one lead by LinkedIn profile URL
  • Get leads from a list — Page leads from a specific list
  • Track performance stats — Pull aggregate acceptance, reply, and InMail metrics for accounts and campaigns

This connector uses API Key authentication. Your users provide their HeyReach API key once, and Scalekit stores and manages it securely. Your agent code never handles keys directly — you only pass a connectionName and a user identifier.

Set up the connector

Register your HeyReach API key with Scalekit so it can authenticate and proxy LinkedIn outreach requests on behalf of your users. HeyReach uses API key authentication — there is no redirect URI or OAuth flow.

  1. Generate a HeyReach API key

    • Sign in to app.heyreach.io and open Dashboard -> Settings -> Integrations -> Get API Key.

    • Create a new API key, give it a descriptive name (e.g., HeyReach Agent), and confirm.

    • Copy the generated key. It is shown only once — store it somewhere safe before navigating away.

  2. Create a connection in Scalekit

    • In Scalekit dashboard, go to AgentKit > Connections > Create Connection. Find HeyReach and click Create.

    • Note the Connection name — you will use this as connection_name in your code (e.g., heyreach).

  3. Add a connected account

    Connected accounts link a specific user identifier in your system to a HeyReach API key. Add accounts 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 HeyReach API key you copied in step 1
    • Click Save.

    Via API (for production)

    await scalekit.actions.upsertConnectedAccount({
    connectionName: 'heyreach',
    identifier: 'user_123',
    credentials: { api_key: 'your-heyreach-api-key' },
    });
Code examples

Once a connected account is set up, call the HeyReach API through the Scalekit proxy. Scalekit injects the API key automatically — you never handle credentials in your application code.

Proxy API calls

import { ScalekitClient } from '@scalekit-sdk/node';
import 'dotenv/config';
const connectionName = 'heyreach'; // connection name from your Scalekit dashboard
const identifier = 'user_123'; // your user's unique identifier
// Get your credentials from app.scalekit.com → Developers → Settings → API Credentials
const scalekit = new ScalekitClient(
process.env.SCALEKIT_ENV_URL,
process.env.SCALEKIT_CLIENT_ID,
process.env.SCALEKIT_CLIENT_SECRET
);
const actions = scalekit.actions;
// Verify the connected API key works — no key needed in your code
const result = await actions.request({
connectionName,
identifier,
path: '/auth/CheckApiKey',
method: 'GET',
});
console.log('API key valid:', result.status === 200);

Scalekit tools

Use execute_tool to call HeyReach tools directly from your code. Scalekit resolves the connected account, injects the API key, and returns a structured response — no raw HTTP needed.

Add leads to a campaign

The most common HeyReach workflow: pick an active campaign, choose a LinkedIn sender account to send from, and add up to 100 leads in a single call. Each lead is bound to a specific sender — so a campaign with multiple senders can round-robin or be sharded by your code.

examples/heyreach_add_leads.py
import scalekit.client, os
from dotenv import load_dotenv
load_dotenv()
scalekit_client = scalekit.client.ScalekitClient(
client_id=os.getenv("SCALEKIT_CLIENT_ID"),
client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"),
env_url=os.getenv("SCALEKIT_ENV_URL"),
)
actions = scalekit_client.actions
# Resolve connected account (API key auth — no OAuth redirect needed)
response = actions.get_or_create_connected_account(
connection_name="heyreach",
identifier="user_123"
)
connected_account = response.connected_account
# Step 1: Pick a campaign and one of its sender accounts
campaigns = actions.execute_tool(
tool_name="heyreach_get_all_campaigns",
connected_account_id=connected_account.id,
tool_input={"limit": 25}
)
campaign = campaigns.result["items"][0] # or filter by name/status
sender_account_id = campaign["campaignAccountIds"][0]
print(f"Adding leads to campaign {campaign['id']} via sender {sender_account_id}")
# Step 2: Add up to 100 leads bound to that sender account
new_leads = [
{"profileUrl": "https://www.linkedin.com/in/jane-doe"},
{"profileUrl": "https://www.linkedin.com/in/john-smith"},
]
result = actions.execute_tool(
tool_name="heyreach_add_leads_to_campaign",
connected_account_id=connected_account.id,
tool_input={
"campaignId": campaign["id"],
"accountLeadPairs": [
{"linkedInAccountId": sender_account_id, "lead": lead}
for lead in new_leads
],
# Auto-resume the campaign if it's paused or already finished
"resumePausedCampaign": True,
"resumeFinishedCampaign": True,
}
)
print(f"Added {len(new_leads)} leads:", result.result)

Look up a lead before reaching out

Verify a lead already exists in HeyReach (and check their tags or enrichment status) before adding them to a campaign — this avoids duplicate outreach and lets you skip leads that are already engaged.

examples/heyreach_get_lead.py
result = actions.execute_tool(
tool_name="heyreach_get_lead",
connected_account_id=connected_account.id,
tool_input={
"profileUrl": "https://www.linkedin.com/in/jane-doe"
}
)
lead = result.result
if lead:
print(f"{lead['fullName']}{lead.get('position') or lead.get('summary')}")
print(f" Company: {lead.get('companyName')}")
print(f" Location: {lead.get('location')}")
print(f" Email: {lead.get('emailAddress') or lead.get('enrichedEmailAddress')}")
else:
print("Lead not found — safe to add to a new campaign.")

Monitor inbox replies

After outreach goes out, poll the unified LinkedIn inbox for unseen replies. Filter by campaign or sender account so you only surface conversations relevant to your agent’s workflow.

examples/heyreach_inbox.py
result = actions.execute_tool(
tool_name="heyreach_get_conversations",
connected_account_id=connected_account.id,
tool_input={
"campaignIds": [campaign["id"]], # filter to one campaign
"seen": False, # only unseen conversations
"limit": 25,
}
)
for convo in result.result.get("items", []):
profile = convo.get("correspondentProfile", {})
messages = convo.get("messages", [])
last_msg = messages[-1] if messages else {}
print(f"📬 {profile.get('fullName')}{profile.get('profileUrl')}")
print(f" {last_msg.get('createdAt')} ({last_msg.get('sender')}): "
f"{(last_msg.get('body') or '')[:120]}")

Track campaign performance

Pull aggregate metrics for one or more campaigns — connection acceptance rate, message reply rate, InMail performance — to power dashboards or trigger follow-up actions when a campaign underperforms.

examples/heyreach_stats.py
# Get all sender accounts associated with the campaign
sender_accounts = campaign["campaignAccountIds"]
stats = actions.execute_tool(
tool_name="heyreach_get_overall_stats",
connected_account_id=connected_account.id,
tool_input={
"CampaignIds": [campaign["id"]],
"AccountIds": sender_accounts,
}
)
# Response wraps aggregates under `overallStats` and a per-day breakdown
# under `byDayStats` — use `overallStats` for top-line numbers.
s = stats.result["overallStats"]
print(f"Campaign {campaign['id']} — '{campaign['name']}'")
print(f" Connection requests: {s['connectionsSent']} sent / {s['connectionsAccepted']} accepted")
print(f" Acceptance rate: {s['connectionAcceptanceRate']:.1%}")
print(f" Messages: {s['messagesSent']} sent / {s['totalMessageReplies']} replied")
print(f" Reply rate: {s['messageReplyRate']:.1%}")

LangChain integration

Let an LLM decide which HeyReach tool to call based on natural language. This example builds an agent that can list campaigns, add leads, and surface inbox replies on demand.

examples/heyreach_langchain.py
import scalekit.client, os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor, create_openai_tools_agent
from langchain_core.prompts import (
ChatPromptTemplate, SystemMessagePromptTemplate,
HumanMessagePromptTemplate, MessagesPlaceholder, PromptTemplate
)
load_dotenv()
scalekit_client = scalekit.client.ScalekitClient(
client_id=os.getenv("SCALEKIT_CLIENT_ID"),
client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"),
env_url=os.getenv("SCALEKIT_ENV_URL"),
)
actions = scalekit_client.actions
identifier = "user_123"
# Resolve connected account (API key auth — no OAuth redirect needed)
actions.get_or_create_connected_account(
connection_name="heyreach",
identifier=identifier
)
# Load all HeyReach tools in LangChain format
tools = actions.langchain.get_tools(
identifier=identifier,
providers=["HEYREACH"],
page_size=100
)
prompt = ChatPromptTemplate.from_messages([
SystemMessagePromptTemplate(prompt=PromptTemplate(
input_variables=[],
template=(
"You are a LinkedIn outreach assistant with access to HeyReach tools. "
"Use heyreach_get_all_campaigns to find campaigns, heyreach_add_leads_to_campaign "
"to enroll new prospects, heyreach_get_conversations to monitor replies, and "
"heyreach_get_overall_stats to report on performance. Always confirm the campaign "
"and sender account before adding leads."
)
)),
MessagesPlaceholder(variable_name="chat_history", optional=True),
HumanMessagePromptTemplate(prompt=PromptTemplate(
input_variables=["input"], template="{input}"
)),
MessagesPlaceholder(variable_name="agent_scratchpad")
])
llm = ChatOpenAI(model="gpt-4o")
agent = create_openai_tools_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
result = agent_executor.invoke({
"input": "Show me unread replies from my active LinkedIn campaigns in the last 24 hours, and tell me which campaign has the highest acceptance rate."
})
print(result["output"])
heyreach_add_leads_to_campaign Add up to 100 leads to an existing HeyReach campaign. The campaign must be in an ACTIVE state (IN_PROGRESS), or use resumeFinishedCampaign / resumePausedCampaign to auto-resume. Each lead is bound to a specific LinkedIn sender account (linkedInAccountId) that will send the outreach. Use heyreach_get_campaign_by_id to find the campaign's sender accounts (campaignAccountIds). Rate limit: 300 requests/minute. 4 params

Add up to 100 leads to an existing HeyReach campaign. The campaign must be in an ACTIVE state (IN_PROGRESS), or use resumeFinishedCampaign / resumePausedCampaign to auto-resume. Each lead is bound to a specific LinkedIn sender account (linkedInAccountId) that will send the outreach. Use heyreach_get_campaign_by_id to find the campaign's sender accounts (campaignAccountIds). Rate limit: 300 requests/minute.

Name Type Required Description
accountLeadPairs array required Array of lead + sender account pairs to add to the campaign (max 100). Each pair binds a lead to the LinkedIn sender account that will reach out. Minimum required per lead: profileUrl.
campaignId integer required The ID of the HeyReach campaign to add leads to. Get campaign IDs from heyreach_get_all_campaigns.
resumeFinishedCampaign boolean optional If true and the target campaign is in FINISHED state, HeyReach will resume it so the new leads can be processed. Defaults to false.
resumePausedCampaign boolean optional If true and the target campaign is in PAUSED state, HeyReach will resume it so the new leads can be processed. Defaults to false.
heyreach_check_api_key Verify that your HeyReach API key is valid and the connection is working. Returns HTTP 200 with empty body on success. Use this to validate a connection before making other API calls. 0 params

Verify that your HeyReach API key is valid and the connection is working. Returns HTTP 200 with empty body on success. Use this to validate a connection before making other API calls.

heyreach_get_all_campaigns List all LinkedIn outreach campaigns in your HeyReach account with pagination. Returns campaign metadata including status (DRAFT, IN_PROGRESS, PAUSED, FINISHED, FAILED), progress stats, associated lead list, and campaignAccountIds (LinkedIn sender account IDs needed for heyreach_get_overall_stats). Rate limit: 300 requests/minute. 2 params

List all LinkedIn outreach campaigns in your HeyReach account with pagination. Returns campaign metadata including status (DRAFT, IN_PROGRESS, PAUSED, FINISHED, FAILED), progress stats, associated lead list, and campaignAccountIds (LinkedIn sender account IDs needed for heyreach_get_overall_stats). Rate limit: 300 requests/minute.

Name Type Required Description
limit integer optional Maximum number of campaigns to return. Defaults to 10.
offset integer optional Number of records to skip for pagination. Defaults to 0.
heyreach_get_all_linkedin_accounts List the LinkedIn sender accounts (connected LinkedIn profiles) in your HeyReach workspace with pagination. Returns each account's ID, name, profile URL, and status. Use the returned account IDs as linkedInAccountId when calling heyreach_add_leads_to_campaign, or as AccountIds in heyreach_get_overall_stats. Rate limit: 300 requests/minute. 3 params

List the LinkedIn sender accounts (connected LinkedIn profiles) in your HeyReach workspace with pagination. Returns each account's ID, name, profile URL, and status. Use the returned account IDs as linkedInAccountId when calling heyreach_add_leads_to_campaign, or as AccountIds in heyreach_get_overall_stats. Rate limit: 300 requests/minute.

Name Type Required Description
keyword string optional Optional search keyword to filter accounts by name.
limit integer optional Maximum number of LinkedIn accounts to return. Max 100. Defaults to 100.
offset integer optional Number of records to skip for pagination. Defaults to 0.
heyreach_get_all_lists List all lead lists in your HeyReach account with pagination. Returns list metadata including name, total lead count, list type, creation date, and associated campaign IDs. Use list IDs with heyreach_get_leads_from_list to retrieve leads. Rate limit: 300 requests/minute. 2 params

List all lead lists in your HeyReach account with pagination. Returns list metadata including name, total lead count, list type, creation date, and associated campaign IDs. Use list IDs with heyreach_get_leads_from_list to retrieve leads. Rate limit: 300 requests/minute.

Name Type Required Description
limit integer optional Maximum number of lists to return. Defaults to 10.
offset integer optional Number of records to skip for pagination. Defaults to 0.
heyreach_get_campaign_by_id Retrieve detailed information about a specific HeyReach campaign by its ID. Returns campaign status, progress stats (total users, in progress, finished, failed), associated lead list, and LinkedIn sender accounts. Use get_all_campaigns first to find campaign IDs. 1 param

Retrieve detailed information about a specific HeyReach campaign by its ID. Returns campaign status, progress stats (total users, in progress, finished, failed), associated lead list, and LinkedIn sender accounts. Use get_all_campaigns first to find campaign IDs.

Name Type Required Description
campaignId integer required The unique ID of the campaign to retrieve. Get campaign IDs from heyreach_get_all_campaigns.
heyreach_get_conversations List LinkedIn inbox conversations across your HeyReach sender accounts with pagination and filters. Returns conversation metadata: participants, last message, seen/unseen status, associated campaign and account. Filter by LinkedIn account IDs, campaign IDs, lead profile URL, tags, search string, or seen status. Useful to monitor replies to outreach sent via heyreach_add_leads_to_campaign. Rate limit: 300 requests/minute. 9 params

List LinkedIn inbox conversations across your HeyReach sender accounts with pagination and filters. Returns conversation metadata: participants, last message, seen/unseen status, associated campaign and account. Filter by LinkedIn account IDs, campaign IDs, lead profile URL, tags, search string, or seen status. Useful to monitor replies to outreach sent via heyreach_add_leads_to_campaign. Rate limit: 300 requests/minute.

Name Type Required Description
campaignIds array optional Filter conversations to these campaign IDs. Get campaign IDs from heyreach_get_all_campaigns.
leadLinkedInId string optional Filter to conversations with a specific lead by their LinkedIn internal ID.
leadProfileUrl string optional Filter to conversations with a specific lead by their LinkedIn profile URL.
limit integer optional Maximum number of conversations to return (1-100). Defaults to 10 — a client-side cap applied in the jsonnet template to protect LLM context, since the HeyReach API's own default (~100) can return 400KB+ payloads. Pass a larger value explicitly if you need more.
linkedInAccountIds array optional Filter conversations to these LinkedIn sender account IDs. Get account IDs from heyreach_get_all_linkedin_accounts.
offset integer optional Number of records to skip for pagination. Defaults to 0.
searchString string optional Free-text search across conversation content and participant names.
seen boolean optional Filter by seen status. true = only seen conversations, false = only unseen. Omit to return both.
tags array optional Filter conversations by lead tags.
heyreach_get_lead Retrieve detailed information about a single HeyReach lead by their LinkedIn profile URL. Returns the lead's profile data (name, headline, location, company, position), email addresses (emailAddress, enrichedEmailAddress, customEmailAddress), tags, and custom fields. Useful to verify a lead exists in HeyReach before or after adding them to a campaign. Rate limit: 300 requests/minute. 1 param

Retrieve detailed information about a single HeyReach lead by their LinkedIn profile URL. Returns the lead's profile data (name, headline, location, company, position), email addresses (emailAddress, enrichedEmailAddress, customEmailAddress), tags, and custom fields. Useful to verify a lead exists in HeyReach before or after adding them to a campaign. Rate limit: 300 requests/minute.

Name Type Required Description
profileUrl string required The public LinkedIn profile URL of the lead to look up. Example: https://www.linkedin.com/in/janedoe
heyreach_get_leads_from_list Retrieve leads from a specific HeyReach lead list with pagination. Returns detailed lead profiles including LinkedIn URL, name, headline, location, company, position, tags, and email addresses. Use heyreach_get_all_lists to find list IDs. Rate limit: 300 requests/minute. 3 params

Retrieve leads from a specific HeyReach lead list with pagination. Returns detailed lead profiles including LinkedIn URL, name, headline, location, company, position, tags, and email addresses. Use heyreach_get_all_lists to find list IDs. Rate limit: 300 requests/minute.

Name Type Required Description
listId integer required The unique ID of the lead list to retrieve leads from. Get list IDs from heyreach_get_all_lists.
limit integer optional Maximum number of leads to return. Defaults to 10 — a client-side cap applied in the jsonnet template to protect LLM context, since lists can hold thousands of leads (observed: 4,054). Pass a larger value explicitly if you need more.
offset integer optional Number of records to skip for pagination. Defaults to 0.
heyreach_get_overall_stats Retrieve overall performance statistics for specific LinkedIn sender accounts and campaigns. Returns aggregate metrics including connection requests sent and accepted, messages sent and replied, InMail stats, and calculated rates (connection acceptance rate, message reply rate). Rate limit: 300 requests/minute. 2 params

Retrieve overall performance statistics for specific LinkedIn sender accounts and campaigns. Returns aggregate metrics including connection requests sent and accepted, messages sent and replied, InMail stats, and calculated rates (connection acceptance rate, message reply rate). Rate limit: 300 requests/minute.

Name Type Required Description
AccountIds array required IDs of the LinkedIn sender accounts (connected LinkedIn profiles) assigned to run this campaign. Each campaign has one or more sender accounts.
CampaignIds array required Array of campaign IDs to retrieve stats for. Get campaign IDs from heyreach_get_all_campaigns.