End-to-End Example
This guide walks you through a complete LinkedIn outreach automation workflow — from connecting an account to sending personalized connection requests and tracking replies.
Step 1: Connect a LinkedIn Account
curl -X POST https://api.we-link.ai/api/v1/login_v2 \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-H "x-api-secret: YOUR_API_SECRET" \
-d '{
"email": "sales@yourcompany.com",
"password": "linkedin-password",
"twoFASecret": "YOUR_2FA_SECRET",
"proxy": { "location": "US" }
}'
Save the returned accountId:
{ "accountId": "550e8400-e29b-41d4-a716-446655440000" }
Step 2: Configure Your Webhook
Set up your server to receive async results:
const express = require("express");
const crypto = require("crypto");
const app = express();
app.use(express.json());
const WEBHOOK_SECRET = process.env.WELINK_WEBHOOK_SECRET;
app.post("/webhook/welink", (req, res) => {
const data = req.body;
// Route by event type
switch (data.status) {
case "SUCCESS":
handleSuccess(data);
break;
case "FAILED":
handleFailure(data);
break;
case "PIN_REQUIRED":
handlePinRequired(data);
break;
}
res.status(200).send("OK");
});
function handleSuccess(data) {
console.log(`✅ Action completed: ${data.request_id}`);
// Store result in your database
db.saveResult(data.request_id, data.result);
}
function handleFailure(data) {
console.error(`❌ Action failed: ${data.error}`);
// Implement retry logic if appropriate
}
app.listen(3000);
Step 3: Send Connection Requests
Now send personalized connection requests with human-like pacing:
const prospects = [
{ profileId: "ACoABC1d2f...", name: "Jane" },
{ profileId: "ACoDFC1def...", name: "John" },
{ profileId: "ACoADC1dhi...", name: "Wade" },
];
async function sendConnections(accountId, prospects) {
for (const prospect of prospects) {
const response = await fetch("https://api.we-link.ai/api/v1/connect", {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": process.env.WELINK_API_KEY,
"x-api-secret": process.env.WELINK_API_SECRET,
},
body: JSON.stringify({
accountId,
profile_id: prospect.profileId,
message: `Hi ${prospect.name}, I'd love to connect!`,
}),
});
const { requestId } = await response.json();
console.log(`📤 Connection queued: ${requestId}`);
// We-Link handles pacing, but space out your API calls too
await sleep(randomBetween(10000, 30000));
}
}
function randomBetween(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
Step 4: Monitor Results
Your webhook receives each result as it completes:
{
"status": "SUCCESS",
"requestId": "1234ab5678290....",
"result": {
"connected": true,
"profile_id": "ACoABC1d2f..."
},
"hash": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...." // hash for verification
}
Key Takeaways
- ✅ Always set up webhooks before initiating actions
- ✅ Space out your API calls with random delays
- ✅ Use the
twoFASecretfor hands-free session management - ✅ Verify webhook signatures before processing
- ❌ Never send requests in parallel for the same account
- ❌ Don't exceed LinkedIn's daily limits