Automate LinkedIn with n8n: Three Workflows That Actually Send
Three workflows that invite, follow up on acceptance and route replies, with each account’s daily budget kept on the server.
n8n’s built-in LinkedIn node has one operation, Create a post, so every outreach workflow on this page runs through the HTTP Request node against an account-based LinkedIn API. Three workflows cover most of what teams build: enrich a profile then invite, follow up when the invitation is accepted, and route replies out of LinkedIn. All three are HTTP Request and Webhook nodes with no custom code.
The part that decides whether they survive is not the wiring. It is that a scheduler has no idea what an account can afford to send, so the sending budget has to live on the server, which is where gtm-api.com keeps it: 20,000+ LinkedIn accounts run on this stack, and under 1% of them have ever been restricted.
On this page
- How the pieces fit together
- Setup: the credential and the nodes
- Workflow 1: invite a list of people
- Workflow 2: follow up when an invitation is accepted
- Workflow 3: send LinkedIn replies to Slack or your CRM
- Why pacing belongs on the server
- What breaks these workflows in production
- Frequently Asked Questions
- Sources
How LinkedIn automation in n8n fits together
An n8n workflow that works LinkedIn has three parts. n8n decides when something happens: a schedule, a new row in a sheet, a form submission, an incoming event. An account-based LinkedIn API does the LinkedIn part through an account you connected to it: it enriches a profile, sends an invitation or a message, and reports what happened on LinkedIn back as events. The connected account is what actually sends, and the pacing section near the end explains why its budget stays with the API instead of in n8n.
Traffic runs both ways. Outbound, an HTTP Request node calls the API, one request per action, all of them on one credential. Inbound, the API pushes a LinkedIn event, such as an accepted invitation or a new reply, to a Webhook node, and that starts the next workflow. The three workflows below are built from exactly those two moves: the first sends invitations, the second waits for acceptances and follows up, the third waits for replies and routes them out of LinkedIn. The setup comes first because all three share it.
Setup: the credential and the nodes
The three workflows below use one credential and three node types. In n8n, create a Header Auth credential under Generic credentials, with the name Authorization and the value Bearer followed by your API token. Every HTTP Request node in every workflow then selects Generic credentials and that one entry. The last row of the table is the alternative: a verified community node that installs from the nodes panel on n8n Cloud and self-hosted alike.
| n8n node | Job in these workflows | Key settings |
|---|---|---|
| HTTP Request | Every outbound call: enrich, invite, message | Method POST, Authentication Generic credentials, Header Auth, Send Body as JSON |
| Webhook | Receives LinkedIn events pushed to the workflow | HTTP Method POST, and the Production URL, see the trap below |
| LinkedIn (built-in) | Publishing posts, and nothing else | Post: Create, as person or organization |
| gtm-api (community node) | Invitations, messages, enrichment and people search as four operations, plus a trigger on three LinkedIn events. Verified, so it runs on n8n Cloud and self-hosted | Search gtm-api in the nodes panel and install n8n-nodes-gtm-api from there. Its own LinkedIn API credential, one API Key field, setup on n8n LinkedIn node |
The base URLs are https://app.gtm-api.com/linkedin/v4 for account actions and https://app.gtm-api.com/orchestration/v4 for webhook subscriptions. What each platform’s built-in LinkedIn app can and cannot do, including Zapier and Make, is on LinkedIn integrations.
Workflow 1: invite a list of people
This workflow takes a list of people, such as profile URLs in a Google Sheet, a form or a CRM, and sends each of them a connection request with a note. Anyone who is already a connection can get a message instead.
Strictly, the enrichment step is optional: the send endpoint accepts the profile URL itself as public_identifier, as well as the LinkedIn URN in the ACoAA... form as profile_id. It earns its place for two reasons: it tells you whether the person is already a connection, and it returns the profile the note is written from.
Three nodes, in order.
- Trigger. Whatever produces profile URLs: a Google Sheets row, a form submission, a CRM webhook. One item per person.
- HTTP Request, enrich. POST to
/api/linkedin-enrichment/person-full-profile. The body takespublic_identifier, which accepts the whole profile URL and reduces it to the slug itself, pluslinkedin_account_sidfor the account you are acting as. - HTTP Request, invite. POST to
/api/linkedin-connection-requests/sendwithprofile_idtaken from the previous node’s response, plus the note.
POST https://app.gtm-api.com/linkedin/v4/api/linkedin-enrichment/person-full-profile
{
"public_identifier": "{{ $json.profile_url }}",
"linkedin_account_sid": "ln_ac_..."
}
POST https://app.gtm-api.com/linkedin/v4/api/linkedin-connection-requests/send
{
"linkedin_account_sid": "ln_ac_...",
"profile_id": "{{ $json.result.profile.ln_id }}",
"note": "{{ $json.note }}"
}
The field worth branching on is result.profile.network_distance: it returns the relationship degree relative to the account you pinned, so an IF node on 1st lets the workflow message existing connections and invite everyone else. Sending an invitation to somebody you are already connected to wastes a slot out of a weekly ceiling that is roughly 100, which LinkedIn connection request limits covers in full.
Workflow 2: follow up when an invitation is accepted
Here the trigger is a person accepting one of your invitations: the moment it happens, n8n sends them a follow-up message. GTM API pushes the acceptance to a Webhook node, and one HTTP Request sends the message.
A webhook beats polling for this. A workflow that checks for acceptances every five minutes spends the account’s read budget on questions that almost always answer “nothing new”, and it still arrives late.
Set the Webhook node’s HTTP Method to POST, publish the workflow, and copy the Production URL. Then register it once, from a terminal or a one-off HTTP Request node.
POST https://app.gtm-api.com/orchestration/v4/api/webhooks
{
"target_url": "https://your-n8n-host/webhook/linkedin-accepted",
"events": ["linkedin-connection-requests.accepted"]
}
The response carries a 32-character hex secret, and it is returned once and masked on every later read, so store it when you see it. Use it to verify the HMAC on incoming calls before the workflow acts on them, because a webhook URL is a public endpoint that anything can post to.
The follow-up step is then a single HTTP Request to /api/linkedin-messages/send, with ln_id for a new thread and text for the body. Wait a realistic interval first. A message that lands in the same second as the acceptance tells the person on the other end it was never written for them.
Workflow 3: send LinkedIn replies to Slack or your CRM
The third workflow sends nothing to LinkedIn. It catches every reply a prospect writes and passes it to where your team works: a Slack notification, a CRM note, a task, a Google Sheets row. The trigger is a second Webhook node subscribed to linkedin-messages.received. Teams that add this one first usually find it is the workflow they actually needed, because the bottleneck in LinkedIn outreach is rarely the sending.
Two more event types earn a place in the same workflow. linkedin-account-smart-limits.limit-reached fires when an account runs out of budget for an action type, which is the signal to stop queueing. linkedin-accounts.login-failed means the session needs attention, and it is worth a direct alert, because an account that is signed out sends nothing and reports no error to your workflow.
Why pacing belongs on the server
The instinct in n8n is to control timing in the workflow: a Wait node between items, a Schedule Trigger at a safe hour, a batch size. That instinct produces a fixed cadence, and it cannot know what the account can afford today.
The budgets that matter sit on the server, per account and per action type, and a workflow inherits them without configuring anything.
- Per-action daily caps, scaled by warm-up. Connection requests default to 25 a day and messages to 50, and both are scaled by a warm-up score from 0 to 100 computed from the account’s age, history and session spread. A new account operates at a fraction of that.
- Spacing. Calls of one kind leave one at a time, about every 30 seconds for invitations and every 10 for messages, each gap varied by up to 20%.
- Only successes count. The counter increments when LinkedIn confirms the action, so a failure costs no budget.
- Recovery windows. When LinkedIn refuses an invitation, the account locks that action for an hour (three for InMail), with no retries until the lock expires.
So the correct n8n design is to push the whole list and let the server hold it back, and to subscribe to the limit event if the workflow needs to know. Every per-action number and how capacity is earned is on LinkedIn limits, and the multi-account arithmetic is on Scaling LinkedIn outreach.
What breaks these workflows in production
Five failure modes account for most of the time lost on these builds, and four of them produce no error message in n8n.
- The wrong webhook URL. n8n registers a test webhook only while you are listening for a test event, and the production one only when the workflow is published. A subscription pointed at the test URL works once during setup and silently never fires again.
- An n8n host the internet cannot reach. The subscription requires an https target on a public address, so a local install needs a tunnel or a cloud instance before any event arrives.
- Registering the same URL twice. One target URL can hold one subscription per team, so a second registration on the same URL is refused, and the first subscription keeps whatever event list it was created with. Put every event type you want in the one
eventsarray. - An invitation note over the cap. The note is capped at 200 characters for a sender without premium and 300 with it, and an over-length note is refused rather than truncated. Trim before sending, or set
allow_no_note_fallbackto send the invitation without the note. - Re-sending to somebody already pending. A second invitation while one is outstanding is refused (
422 resend_not_available), and after a withdrawal the same person waits 21 days. Filter your list against what is already in flight.
Frequently Asked Questions
How do I send a LinkedIn connection request from n8n?
Through the HTTP Request node, calling an account-based LinkedIn API. n8n’s built-in LinkedIn node only creates posts, and LinkedIn’s own API does not expose invitation sending outside a closed partner program. The send endpoint takes the profile URL directly as public_identifier, and an enrichment call in front of it tells you who is already a connection.
Which n8n node do I use for LinkedIn outreach?
HTTP Request for every outbound action and Webhook for inbound events, and no custom code node is needed for any of the three workflows on this page. There is also a verified community node, n8n-nodes-gtm-api, with the invitation, message, enrichment and people-search calls as four operations plus a trigger on three LinkedIn events, and it installs from the nodes panel on n8n Cloud and self-hosted alike. Install, credential and operations are on the n8n LinkedIn node page. The built-in LinkedIn node stays useful for publishing posts and can sit in the same workflow on its own credential.
Why does my n8n webhook never fire?
Almost always one of three things. The subscription points at the Test URL, which only exists while n8n is listening for a test event. The Production URL is the one that appears when the workflow is published. Or the n8n host is not reachable from the internet, so the delivery cannot land. Or the workflow was never published after the webhook node was added.
How do I stop an n8n workflow from overrunning LinkedIn’s limits?
By not pacing it in n8n. Wait nodes and schedule triggers produce a fixed cadence, and they cannot know the account’s current ceiling. An account-based API enforces per-action daily budgets and the spacing between calls on the server, so the workflow can push the whole queue and subscribe to the limit-reached event if it needs to react.
Do these workflows need self-hosted n8n, or does Cloud work?
Both work for the sending side, since those are ordinary outbound HTTP calls. The webhook workflows need an address the internet can reach, which n8n Cloud provides by default and a local install does not. A self-hosted instance behind a firewall needs a tunnel or a public hostname before any event is delivered.
Sources & Further Reading
- n8n, LinkedIn node reference (the single Post: Create operation), read 20 August 2026
- n8n, HTTP Request node (generic credentials, Header Auth, Send Body as JSON), read 20 August 2026
- n8n, Webhook node (the Test URL is registered on Listen for Test Event, the Production URL when the workflow is published), read 20 August 2026
- n8n, community node catalog entry for n8n-nodes-gtm-api (both nodes marked verified and published on 7 October 2026), read 7 October 2026
- gtm-api.com, developer documentation (the endpoints, request fields and webhook event names used above)
- Per-action defaults, warm-up scaling and recovery windows come from the engine running 20,000+ connected accounts
- Related: LinkedIn integrations · LinkedIn limits · LinkedIn connection request limits · LinkedIn API: the developer guide · Scaling LinkedIn outreach · n8n LinkedIn node
Wire it once, and let the server hold the queue back.
One credential, ordinary HTTP nodes, and per-account budgets enforced before anything reaches LinkedIn. On that stack, gtm-api.com runs 20,000+ accounts with under 1% of them ever restricted. Free plan, then from $10 per account at volume.
Last updated: October 2026 · Definitions and benchmarks verified at time of publication
