Skip to content
← Processes

Run LinkedIn outreach at a safe pace

Small sending slots through the day, a daily budget that climbs one step only while the account stays healthy, and every send stopped at the first warning.

LinkedIn→Lemlist→Slack
Starts
Daily schedule in short slots
Steps
7
Checks and gates
1
A person decides
Never, runs alone

Trigger · Schedule

Daily schedule in short slots

Several small runs spread across each weekday share the day's budget, so nothing goes out in one burst.

Claude runs the rest autonomously

  1. 1

    AI checks the account before any send.check

    LinkedIn

    LinkedIn

    The session has to answer alive, and nothing is written after a pause, a checkpoint or an earlier block the same day.

  2. 2

    AI sets the day's budget from account health.

    Once a day the level moves down on any warning, up one step only when every health test passes, and stops everything on a restriction.

  3. 3

    AI records replies and acceptances.

    LinkedIn

    LinkedIn

    Anyone who answered on either channel is marked replied and paused in the email sequence, and new connections are stamped with their date.

    Lemlist

    Lemlist

  4. 4

    AI sends the due messages.

    LinkedIn

    LinkedIn

    Follow-ups that are due go first, then first messages to the people who accepted, each one re-read just before it leaves.

  5. 5

    AI invites after a fresh profile check.

    LinkedIn

    LinkedIn

    Each queued profile is read again first, so someone who left is dropped, a connection already made skips the invitation, and a pending one is never sent twice.

  6. 6

    AI withdraws stale pending invitations.

    LinkedIn

    LinkedIn

    Invitations left pending for weeks are withdrawn a few at a time, which keeps the backlog small enough for the budget to climb.

  7. 7

    AI posts the weekly recap.

    Slack

    Slack

    Once a week one message gives invitations, acceptance, messages, replies by name, the current level and the backlog left.

LinkedIn outreach usually fails the same way. Someone imports a list into a tool, sets it to send fifty invitations a day from the first morning, and two weeks later the account is asking for a verification code. Or the opposite: the team, burned once, sends by hand when it remembers, the pending invitations pile into the hundreds, and nobody knows whether the account could take more. Neither version knows how the account is actually doing, and neither changes its pace when the answer changes.

The signals are all there. The account says whether its session is alive, the invitations you sent say how many were accepted, the inbox says who replied, and the pending list says how much is still hanging. A pace set from those signals, reviewed every morning and written down, is the join, and it is work an agent can do in small slots through the day without getting bored of it.

What you get

Invitations and messages go out from your own LinkedIn account in small slots under a budget that only rises while the account is healthy, replies on either channel stop the sequence, stale invitations are cleared, and a weekly recap says where things stand.

What each slot reads before it sends

Every slot opens on the account itself. The LinkedIn session has to answer alive, and a governor row says whether sending is active, on hold or paused, at which level, since when and why. A pause, a dead session or an earlier block the same day means the slot writes nothing at all.

Then it reads what happened since the last slot: replies in the inbox, judged on who sent the last message rather than on the message's own flag, replies to the same people's emails in lemlist, and connections that accepted. A reply on either channel marks the person replied and pauses their email lead, so nobody gets a follow-up after they have answered. Only then does it send: due follow-ups first, then first messages, then invitations, each within the slot's share of the day. Once a week the result goes to the team in Slack.

What makes LinkedIn outreach pacing hold up

The budget moves on evidence, one step at a time. A ladder such as 5, 8, 12, 15 and 20 invitations a day is climbed only after five weekdays at the current level, a week with no blocked run, an acceptance rate that holds up on invitations old enough to have been answered, a pending backlog small enough for the next level, and enough people queued to need the speed. One limit warning drops it a level and holds it for a week. A checkpoint or a restriction pauses everything until a person resumes the account, and the run never lifts a pause on its own.

Every invitation is preceded by a fresh read of the profile. The identifier that comes back has to be the one asked for, because a mismatch is LinkedIn redirecting onto someone else. Someone who has left the company is dropped and their email lead paused. Someone already connected skips straight to the message, and an invitation already pending is never sent a second time. Before the first invitation of the slot, the account's own sent list is counted for today, which catches any other tool or person sending from the same seat.

The pending list is drained as deliberately as the queue is filled. Your own invitations left unanswered for about three weeks are withdrawn a few per slot, and once a week the older pending invitations on the account are listed and worked off oldest first. No two LinkedIn writes ever run back to back or in parallel, a failed write is never retried in the same slot, and a missed slot is never caught up.

A recap the team can read in ten seconds

Once a week, after the last slot, one message lands in the sales channel: invitations, acceptances and the acceptance rate, messages and replies, the current level and any change with its reason, the stale invitations cleared and left, and the replies of the week by name and channel. Rates under ten data points say "too early" rather than a percentage, and a number that could not be computed says "n/a". The recap is built from the timestamps every slot writes, which is why every slot writes them.

For how this compares with the browser extensions, desktop apps and cloud sequencers people usually reach for, see LinkedIn automation tools: which kind is safer.

The prompt

The real prompt behind the steps above, detailed enough that an agent with the same tools can run it as written. The Run buttons copy the full version, which also carries the steps for connecting those tools.

# Run LinkedIn outreach at a safe pace

You have access to your own LinkedIn session, your cold email
sequencer, a team messaging tool, and three tables you can read and
write. Run this **[several times each weekday, for example five slots
spread two hours apart]** for **[the outreach queue of people you
want to reach on LinkedIn]**.


## 1. Check the account before any send

### The tables this run keeps

- **The governor**: one row holding `status` (active, hold or
  paused), `level`, `invites_per_day`, `messages_per_day`,
  `level_since`, `hold_until`, `last_eval`, `last_reason`, and a
  `history` field that gets one dated line per change and is never
  rewritten.
- **The outreach queue**: one row per person, keyed on the
  normalized LinkedIn URL, with the person's provider id once known,
  a connection note (200 characters at most), a first message and a
  follow-up, written in advance and **sent verbatim, never edited by
  the run**. Its LinkedIn stage moves queued → invited → connected →
  first message sent → follow-up sent; any of them → replied; invited
  → withdrawn; or skipped. Each move stamps its own timestamp. When
  the person is also in an email sequence, the row carries that
  lead's id and campaign.
- **The stale invitation backlog**: pending invitations older than
  **[30 days]** waiting to be withdrawn, with a status of to
  withdraw, withdrawn, gone or error.

**This is the only thing allowed to send from the account
automatically.** Any other LinkedIn campaign becomes a new set of
rows in the queue, under the same budget, never a second sender on
the same seat.

Every slot starts here, and protecting the account comes before
volume. When in doubt, do less and say why in the report.

- Read the governor. `status = paused` means no LinkedIn write at
  all in this run: stop and report that a person has to set it back
  to active. `status = hold` runs normally at the current level; hold
  only blocks promotion.
- Check the LinkedIn session's status. Anything other than alive:
  set the governor to paused with the reason and the date, append a
  history line, and stop.
- If an earlier slot today stopped on a block, this slot writes
  nothing to LinkedIn.
- Weekends and public holidays: do nothing.

## 2. Set the day's budget from account health

Once a day, in the first slot, before any send, review the level and
stamp `last_eval` with today's date. The ladder is **[your levels,
for example 5, 8, 12, 15 and 20 invitations a day, with messages at
the same figures]**. Never skip a level and never go above the top
one.

- **Demote** one level (never below the first) when, since the last
  review, a run stopped on a limit-type error (429, "limit", "too
  many", "weekly"), or when acceptance on invitations sent **[7 to
  21 days]** ago fell under **[10%]** with at least **[20]** of them.
  Set `level_since` to today, set `status = hold` with `hold_until`
  **[7 days]** out, and append the reason to the history.
- **Pause** everything when any run reported a checkpoint, a
  captcha, a verification request, a restriction or a session that is
  no longer alive. All writes stop until a person resumes them. The
  run never sets `status` from paused back to active itself.
- **Promote** one level only when every test passes: at least
  **[5]** weekdays at the current level and any hold has expired; no
  blocked run in the last 7 days; acceptance on invitations sent 7 to
  21 days ago of at least **[20%]** when there are 10 or more of them
  (with fewer, skip this test); a stale backlog small enough for the
  level you are moving to (**[the smaller the backlog has to be, the
  higher the level]**); and at least twice the new daily cap still
  queued, since there is no reason to go faster with nothing to send.
- Otherwise leave the level alone and write the test that failed into
  `last_reason`.

Each slot then works within its share of the day: invitations and
messages each capped at the daily figure divided by the number of
slots, rounded up, withdrawals at **[6]** per slot, profile lookups
at twice the slot's invitation cap. The daily caps are counted from
the queue's own timestamps for today.

## 3. Record replies and acceptances

Reads only, plus one email-side pause.

- **Email replies.** For each email campaign the queue's people are
  in, list the leads that replied (also those marked interested or
  not interested). Match them to queue rows and mark them replied
  with the time, unless they already are.
- **LinkedIn replies.** Read the first page of the inbox. For each
  row that is invited, connected or mid-sequence, find its thread by
  the stored chat id or the attendee's provider id. If the last
  message's sender id is not your own account's id, the person
  replied: mark the row replied with that message's time, store the
  chat id, and **pause that person's lead in the email sequence**.
  Never trust the message's "is sender" flag; it has been seen false
  on every thread of an account, including the account's own.
- **Acceptances.** Read the first page of your connections, newest
  first. A connection matching an invited row, on provider id or on
  the slug of its LinkedIn URL, moves to connected with the
  connection's own date.
- Add a dated note to each row saying which channel the reply came
  from.

## 4. Send the due messages

Up to the slot's message cap, within the day's cap.

1. Follow-ups first: rows whose first message went out at least
   **[6 days]** ago get the follow-up, in the existing thread when
   there is one, otherwise to the person's provider id.
2. Then first messages: connected rows, oldest connection first.
   Store the chat id that comes back.

Re-read each row just before sending it. A row that became replied
or excluded since the slot started is skipped.

## 5. Invite after a fresh profile check

Before the first invitation of the slot, read the first page of
invitations the account has sent and count the ones created today.
That count plus this slot's planned invitations must stay within the
daily cap; lower this slot's number if not. This is what catches any
other sender on the account.

Take queued rows in **[your priority order, for example people with
no email address first, then by fit score with the freshest leads
ahead of the older backlog]**. For each:

1. Read the profile by its public identifier. The identifier that
   comes back must be the one you asked for: a mismatch is a redirect
   onto someone else. Mismatch or not found → skipped, "profile not
   resolved".
2. Clearly left the company → skipped and excluded, with the reason
   and the date, and their email lead paused.
3. Already a first-degree connection → connected, nothing to send.
   An invitation already pending → invited, nothing to send.
4. Otherwise send the invitation with the stored note, and stamp the
   row invited with the provider id, the time and the invitation id
   when one comes back.

## 6. Withdraw stale pending invitations

At most the slot's withdrawal cap.

1. Your own rows first: invited more than **[21 days]** ago with an
   invitation id → withdraw it and mark the row withdrawn. "Not
   found" means it was answered: check the profile once, connected if
   first degree, otherwise skipped as declined.
2. Then the backlog, oldest first: withdraw, mark withdrawn with the
   time; already gone → gone; any other error → error with a note,
   and stop this step for the slot.
3. Once a week, in the first slot, refill the backlog: page through
   the account's sent invitations with the returned cursor, at most
   **[8 pages]**, stopping at the first page whose old invitations are
   all already listed, and add each invitation older than [30 days]
   that is not there yet, keyed on its invitation id.

A long tail of pending invitations is one of the things that holds an
account back, which is why the promotion test in step 2 reads the
backlog's size.

### Pacing and stop rules, for every step

- Never two LinkedIn writes back to back: put a read or a table write
  between any two sends, invitations or withdrawals. Never send in
  parallel calls.
- Any error mentioning 429, "limit", "too many" or "weekly": stop
  every LinkedIn write and report the run as blocked, quoting it. The
  next daily review demotes.
- Any error mentioning a checkpoint, a captcha, verification, a
  restriction or a dead session: stop, set the governor to paused
  with the reason, append the history, report blocked.
- An invitation refused because of its note is never resent without
  the note: stop and report it.
- Never retry a failed LinkedIn write in the same slot. Never catch
  up a missed slot or a missed day.

## 7. Post the weekly recap

Once a week, after the last slot of **[the last working day]**, read
the tables and the week's runs and post **one** message to **[your
team's sales channel]**. Read-only everywhere else.

- Count with aggregates, never by pulling every row: invitations
  this week and to date; acceptances this week and to date;
  acceptance rate on invitations sent at least 7 days ago ("too
  early" under 10 of them); messages this week (first messages plus
  follow-ups); replies this week and to date, and the reply rate on
  people who received a first message ("too early" under 10); people
  still queued, and the weeks of work that leaves at the current daily
  cap; stale invitations withdrawn this week and left.
- Replies this week by name, company and channel, at most **[8]**, then
  "+N more".
- The level and its daily caps, with any change this week from the
  governor's history and its reason.
- Health: green when active with no blocked run this week, amber on
  hold or after a limit block, red when paused, with one line saying
  why when it is not green.
- Numbers in bold, no commentary, no advice, under **[900]** characters.
  A metric that could not be computed shows "n/a"; never estimate
  one. If the post is refused, report it; never post twice.

## Never

Send anything that is not stored in the queue, edit the stored copy,
contact a row that replied, was skipped, withdrawn or excluded, start
or resume anything in the email sequencer (pausing a lead on a reply
is its only write there), exceed the governor's caps or top level, or
lift a pause.

## Output

Report, per slot: the governor's level and caps and any change with
its reason, invitations sent (who), messages sent (who, first or
follow-up), acceptances, replies by channel, withdrawals (yours and
backlog), the account's invitations today, skips with their reasons,
the queue's stage counts and the backlog left. Only actions the tools
confirmed.

Why run it with Tulina

A prompt helps one person. A process moves a team.

Pasted into a chat, the prompt above works once, for whoever pasted it. In Tulina, "Run LinkedIn outreach at a safe pace" becomes a process the team shares, that keeps its history, runs on its own, and stays inside the same security perimeter as the tools it calls.

  • The whole team works on the same one

    PersonalTeamOrganisation

    A process lives where it belongs: yours, your team's or the whole organisation's. Whoever runs it can improve it, and everyone starts from the best version instead of explaining the job again.

  • Every edit is a version

    v1v2v3

    Each change is a new version with the previous one kept, so a bad edit is undone by restoring an earlier one. Every run records the version it followed, and what a run teaches goes back into the process.

  • It runs without you

    schedulewebhookon demand

    A hosted agent runs the process on Tulina's own infrastructure, on a schedule or when an event arrives, and keeps going when you close the chat. Nothing to host. Every run is tracked to its outcome.

  • Inside the same security perimeter

    vaultrolesrun log

    Credentials stay in the vault, never in the prompt. Roles decide who may run what, every call is logged, and a step a person has to approve waits for that person.

Questions about safe LinkedIn outreach automation

There is no single published number, so this process does not assume one. It starts low, for example five invitations a day, and climbs one step at a time, for example to 8, 12, 15 and 20, only after a week at the current level with no blocked run, a healthy acceptance rate and a small backlog of pending invitations. Any limit warning drops it a level and holds it there.

By spreading the day's budget over several small slots instead of one burst, never placing two LinkedIn writes back to back, and treating a checkpoint, a captcha or a restriction as a full stop. When one appears, every send pauses until a person resumes the account by hand; the run never lifts a pause itself.

Yes, and here it is part of the pacing. Your own invitations left pending for about three weeks are withdrawn a few per slot, and once a week the account's older pending invitations are listed and drained the same way. The budget is only allowed to rise once that backlog is small enough for the next level.

It does. Each slot reads the inbox and the email replies, marks the person replied on whichever channel they answered, and pauses their lead in the email sequence. Pausing a lead on a reply is the only thing the run ever writes in the sequencer.

Other processes that run mainly on LinkedIn. The tools they share with this one are lit.

See Tulina in a 30-minute demo.

Book a demo