---
title: "Call the createLeadMagnetCampaign MCP tool"
method: POST
path: "/api/v1/actions/createLeadMagnetCampaign"
tags: ["Actions"]
---

# Call the createLeadMagnetCampaign MCP tool

`POST /api/v1/actions/createLeadMagnetCampaign`

## Request

- Base URL: `https://app.reachium.io`
- URL: `https://app.reachium.io/api/v1/actions/createLeadMagnetCampaign`
- Auth: HTTP bearer

Build a DRAFT lead-magnet campaign: hook post + trigger keyword + what to send (a resource document delivered as a tracked link, and/or a delivery_message you write) + the public comment reply, plus sender_account_ids. The delivery DM is ONE message that sits on both branches of the sequence (connected now / after connecting); follow-ups are separate no-reply steps. Supplied delivery_message / comment_reply are stored verbatim; omitted copy is generated with any offer line placed verbatim. The result carries warnings (keyword missing from the hook post body, keyword shared with other campaigns, generated copy that needed the fallback template), copy_warnings (house-rule violations in any delivery_message, comment_reply or followups you supplied, never rewritten), sender_resolution, and untruncated delivery_copy; read everything back later with getCampaignSequence. If the user has not stated they specifically want a lead-magnet funnel (for example a bare "I need to reach a lot of people"), pull getPlaybook("campaigns", "choosing-a-campaign-type") FIRST - lead magnet is the inbound-from-content type, and it is the wrong pick for a user with no existing content reach or who needs meetings this week. Otherwise pull getPlaybook("content", "lead-magnet-funnel") and getPlaybook("copywriting", "lead-magnet-copy") FIRST: keyword choice and CTA shape make or break the funnel. Optional followups (max 4) add no-reply nudges after the delivery DM. Stays a draft until activated with activateCampaign (launch scope required) or in /campaigns. An UNPUBLISHED hook post (draft, planned, approved, or scheduled) arms the funnel when it publishes; an ALREADY-PUBLISHED Reachium post is also accepted and pre-arms the funnel, and on activation everyone who already commented the keyword is enrolled retroactively (throttled) - surface the result notes so the user expects that backlog send. A published post is refused only when another campaign already hooks it or it has no LinkedIn URN. Surface returned warnings and copy_warnings to the user.

Called through the Actions bridge: the response is that tool's own result, wrapped as `{ data: <tool result> }` under HTTP 200. Billing, daily-cap, and confirm-step outcomes are embedded INSIDE `data`, never remapped to an HTTP status (see the templated `/api/v1/actions/{toolName}` operation above for the full protocol, and `x-mcp-actions` for this tool's machine-readable scope/cap/confirm_behavior fields). Authentication, request-shape, and optional idempotency-protocol failures still use their documented non-200 statuses.

## Headers

- `Idempotency-Key` string

## Request body

- object
  - `post_id` string, uuid, required: The hook post. Unpublished arms on publish; already-published (via Reachium) pre-arms and back-enrolls existing keyword commenters.
  - `document_id` string, uuid: The lead-magnet document to deliver as a per-lead tracked {{document_link}}. Optional when delivery_message is supplied (call-first offers, waitlists, plain answers need no document); required otherwise.
  - `keyword` string, required: The comment keyword that triggers delivery. Short and distinctive - never a word that hides inside other words.
  - `name` string: Human name for the campaign. Lead with WHAT it is - the offer, audience or goal - then any context, e.g. "10 DM Templates - Gabriel Palacios - SYSTEM". For a lead magnet that means the offer first, then the audience or author, then the trigger keyword. The " (Rio)" suffix is added automatically. Defaults to the bare trigger keyword, which reads poorly in the campaigns list, so pass a real name.
  - `offer` string: Optional booking/offer line to weave into the delivery DM. Omit for resource-only.
  - `followups` object[]: Up to 4 no-reply follow-ups after the delivery DM (e.g. a booking nudge).
    - `message` string, required: Follow-up DM if the lead does not reply; use {{first_name}}.
    - `wait_days` integer, required: Days after the previous message (1-14).
  - `delivery_message` string: Write the private delivery DM yourself; stored VERBATIM on both branch nodes (no generation). Use {{first_name}}; include {{document_link}} exactly when document_id is given. Omit to have it generated from the brand profile with the offer line placed verbatim.
  - `comment_reply` string: Write the public comment reply yourself; stored VERBATIM. No links (it is public). Omit to have it generated.
  - `sender_account_ids` string[]: LinkedIn account ids (getCampaignSenderAccounts) that send the reply and DM. Omit and the hook post's own publishing account is attached when the post publishes; a hook that is already live needs this set or activation refuses.

## Response `200`

The result of calling this tool.

- object
  - `data` unknown, required
  - `error` unknown, required

## Other responses

- `400`: The request body was not a JSON object (code invalid_request), or Idempotency-Key is malformed (code invalid_idempotency_key).
- `401`: Missing or invalid API key. Send `Authorization: Bearer rmcp_...` (code unauthorized).
- `403`: This tool is out of the key’s granted scope (code insufficient_scope).
- `409`: This Idempotency-Key has an unresolved in-flight or ambiguous result (code request_in_flight). Reconcile before using a new key.
- `422`: This Idempotency-Key was already used with a different request body (code idempotency_key_reuse).
- `429`: Rate limited: shared `mcp:ip:{ip}` (600/60s) or `mcp:key:{keyId}` (120/60s) bucket, the SAME buckets the MCP endpoint uses (code rate_limited).
- `500`: Unhandled server error (code internal_error).

---

[API](https://skmtc.dev/reachium/apis/reachium-api.md) · [All operations](https://skmtc.dev/reachium/apis/reachium-api/llms.txt) · [OpenAPI document](https://skmtc.dev/reachium/apis/reachium-api/revisions/30c16b30b499?raw)
