Search documentation

Jump to any section of the Crispy docs

Guides

Post engagement campaigns

Cold outreach interrupts someone who never asked to hear from you. Post engagement flips that: when somebody reacts to or comments on a post about your topic, they have publicly raised their hand, with a timestamp.

How it works

Crispy pulls the people who engaged with a post directly off that post and scaffolds a campaign from them. The whole flow is four tools and it ends with a preview you approve before anything sends.

  1. search_posts — find posts about your topic by keyword
  2. list_post_reactions and list_post_comments — pull the people who engaged
  3. build_campaign — create the list, add contacts, enroll them against your policy
  4. preview_campaign_launch then confirm_campaign_launch — review, then go live

The prompt

Paste this into your agent, then answer the two questions it asks.

You have the Crispy MCP tools connected to my LinkedIn account.

I want to build a campaign from people who engaged with posts about a topic.

Ask me for two things first:
  1. The topic or keyword to search posts for.
  2. What I want the campaign to be called.

Then:

1. Call search_posts with my keyword (limit 10). Show me the results as a numbered
   list: author, a one-line summary of the post, and the engagement counts. Ask me
   which post or posts to pull people from. Do not pick for me.

2. For each post I choose, call list_post_reactions (limit 100) and
   list_post_comments. Collect the people.

3. Before you show me anything, deduplicate by provider_id. The same person often
   both reacts and comments, and appears on several posts.

4. Show me the collected people with, for each one: name, headline, and their
   crispy_context flags. Every person carries a crispy_context block, so read the
   flags inside it, not its presence. Group them:
      - NEW — is_connection false, invitation_pending false, invitation_accepted false
      - KNOWN — is_connection true, or an invitation already sent
   Also call out anyone with viewed_your_profile true. They looked at me already,
   which makes them the warmest people in the set regardless of which group they
   land in.
   Each person also carries network_distance (FIRST_DEGREE, SECOND_DEGREE,
   THIRD_DEGREE). Report the spread — it tells me whether this audience is
   reachable by invitation or needs a different approach.
   Tell me the count of each. Ask me whether to include the KNOWN group. Default to
   NEW only unless I say otherwise.

5. Call build_campaign with the name I gave and the people I approved. Pass each
   person as { identifier: "<their provider_id>" }. Use kind "acquisition" for people
   I am not connected to.

   build_campaign creates the list, adds the contacts, creates the campaign, and
   enrolls them against my enrollment policy. It does NOT launch. Report back exactly
   who was enrolled and who the policy skipped, with the skip reason for each.

6. Stop. Tell me the campaign is scaffolded but not live, and that the next step is
   writing the sequence.

Do not call confirm_campaign_launch at any point in this conversation. I will launch
it myself after reviewing the preview.

Known issue

Over the REST API, ?limit= is currently rejected on list_post_comments. Call it without a limit, or use MCP or the CLI where the parameter works as documented.

Write the sequence, then preview

Once the campaign exists, set the messages with manage_outreach. Step 1 should reference the specific post they engaged with, not a generic opener — that is the entire point of this workflow.

Then always call preview_campaign_launch. It renders up to ten real first-touch messages exactly as they will send, plus any blacklist and duplicate hits in the list. It is read-only. Nothing sends. Read those ten messages as if you were receiving them.

When you are satisfied, confirm_campaign_launch flips the campaign live. It refuses with a structured reason if the campaign is not ready — no bound list, or a relationship campaign with an empty message.

Why the prompt is shaped this way

Deduplicate before showing. One person reacting and commenting on the same post is two records. Across three posts they can be six. Without a dedupe step your “80 prospects” is more like 40, and some get enrolled twice.

Read the context flags, not the block. Every person comes back with a crispy_context block carrying is_connection, invitation_pending, invitation_accepted and viewed_your_profile. The block is always present, so its presence tells you nothing. Sending a stranger-opener to someone you are already connected to is the most common way this workflow embarrasses you.

Never let the agent launch. The prompt forbids confirm_campaign_launch explicitly. Scaffolding is reversible. Sending is not. Crispy splits these into two tools for exactly that reason.

Read the skip reasons. build_campaign runs your enrollment policy and will skip people: already connected, already in another campaign, on your blocklist, messaged recently. Those skips are the guardrails working. A surprisingly high skip count is information about your list, not an error.

Limits worth knowing

  • search_posts returns 1-25 results per call. Searches share a daily cap with search_people and search_companies (300/day by default).
  • list_post_reactions returns 1-100 per call, with a cursor for more.
  • Reactors are saved to your connections automatically as a side effect of listing them, so they stay searchable even if you do not enroll them now.

Variations

A competitor’s audience. Find a competitor post that did numbers and pull the reactors. These are people interested in the category.

Your own post. If something you posted performed, the people who engaged are your warmest possible list. Use kind: "relationship" if most are already connections.

Recurring. Re-run the same search weekly. Enrollment is policy-checked, so people already in the campaign are skipped rather than duplicated.

See also the Campaigns guide for the two outreach modes and how sequences execute.