Warm Outreach

Warm Outreach Campaign

This guide walks through a complete outreach workflow: finding qualified leads, sending connection requests with personalized notes, monitoring for acceptance, and sending follow-up messages.

Step 1: Find 2nd-Degree Connections

Search for people at your target company who are 2nd-degree connections (you share mutual connections):

curl -s "$BASE/api/search/people?keywords=VP+Engineering&company=Stripe&network=S&count=20" \
-H "Authorization: Bearer $KEY" \
-H "X-User-Id: $USER"

Step 2: Check Relationship Status

Before connecting, verify the target is not already connected or has a pending invitation:

curl -s -X POST "$BASE/api/relationships/read" \
-H "Authorization: Bearer $KEY" \
-H "X-User-Id: $USER" \
-H "Content-Type: application/json" \
-d '{"profiles": [{"vanityName": "target-person"}]}'

Check the response:

  • connected: false — Good, not yet connected
  • pendingInvitationSent: false — Good, no pending request
  • canConnect: true — Good, connection is allowed

Do not send a connection request if pendingInvitationSent: true. LinkedIn may restrict your account for sending duplicate requests.

Step 3: Get Their Recent Posts

Find a conversation opener by checking what they have been posting about:

curl -s "$BASE/api/posts?profileUrl=https://www.linkedin.com/in/target-person/&limit=5" \
-H "Authorization: Bearer $KEY" \
-H "X-User-Id: $USER"

Use a recent post topic to personalize your connection note.

Step 4: Send Connection Request

Send a connection request with a personalized note (max 300 characters):

curl -s -X POST "$BASE/api/connect" \
-H "Authorization: Bearer $KEY" \
-H "X-User-Id: $USER" \
-H "Content-Type: application/json" \
-d '{
"profileUrl": "https://www.linkedin.com/in/target-person/",
"message": "Hi Jane, I noticed your recent post on distributed systems at Stripe. Would love to connect and exchange ideas."
}'

Space connection requests by at least 60 seconds. Keep daily volume under 20 for new accounts, under 40 for established accounts. Voyager tracks connectionsRequested via GET /api/session/capabilities.

Step 5: Monitor for Acceptance

Set up a webhook for connection acceptance events:

curl -s -X POST "$BASE/api/webhooks" \
-H "Authorization: Bearer $KEY" \
-H "X-User-Id: $USER" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.com/webhook",
"events": ["connection_accepted"],
"secret": "your-hmac-secret"
}'

Option B: Poll Events

curl -s "$BASE/api/events?types=connection.received&since=2026-03-15T00:00:00Z" \
-H "Authorization: Bearer $KEY" \
-H "X-User-Id: $USER"

Step 6: Send Follow-Up Message

After the connection is accepted, send your first message. Wait at least a few hours for the interaction to feel natural:

curl -s -X POST "$BASE/api/send" \
-H "Authorization: Bearer $KEY" \
-H "X-User-Id: $USER" \
-H "Content-Type: application/json" \
-d '{
"profileUrl": "https://www.linkedin.com/in/target-person/",
"message": "Thanks for connecting, Jane! I wanted to share an article we published on scaling microservices that I thought you might find interesting given your work at Stripe."
}'

Complete Campaign Flow

export BASE=https://li.scaleabm.org
export KEY=voy_YOUR_API_KEY
export USER=your-username
# 1. Search for leads
LEADS=$(curl -s "$BASE/api/search/people?keywords=Head+of+Sales&company=HubSpot&network=S&count=10" \
-H "Authorization: Bearer $KEY" -H "X-User-Id: $USER")
# 2. For each lead, check relationship
for VANITY in $(echo "$LEADS" | jq -r '.data.results[].vanityName'); do
REL=$(curl -s "$BASE/api/relationship/status?profileUrl=https://www.linkedin.com/in/$VANITY/" \
-H "Authorization: Bearer $KEY" -H "X-User-Id: $USER")
CONNECTED=$(echo "$REL" | jq -r '.data.connected')
PENDING=$(echo "$REL" | jq -r '.data.pendingInvitationSent')
if [ "$CONNECTED" = "false" ] && [ "$PENDING" = "false" ]; then
# 3. Get their posts for personalization
POSTS=$(curl -s "$BASE/api/posts?profileUrl=https://www.linkedin.com/in/$VANITY/&limit=3" \
-H "Authorization: Bearer $KEY" -H "X-User-Id: $USER")
# 4. Send connection request
curl -s -X POST "$BASE/api/connect" \
-H "Authorization: Bearer $KEY" -H "X-User-Id: $USER" \
-H "Content-Type: application/json" \
-d "{\"profileUrl\":\"https://www.linkedin.com/in/$VANITY/\",\"message\":\"Hi, your work at HubSpot caught my eye. Would love to connect.\"}"
sleep 60 # Space requests apart
fi
done

Error Handling

ErrorMeaningAction
422 on /api/connectAlready connected or pendingSkip this lead
403 on /api/sendNot connected, not Open ProfileSend connection request first
Rate limit on connectionsLinkedIn weekly limit reachedPause and resume tomorrow