create_update_linkedin_message_ad
Create a new or update an existing LinkedIn Message Ad on the Metadata platform.
Destructive creative
Deletes, archives, launches or moves budget. Do not give an agent this one without a human gate.
What it does
Create a new or update an existing LinkedIn Message Ad on the Metadata platform.
A LinkedIn Message Ad is a Sponsored Messaging asset: a one-shot direct
message delivered to a member's LinkedIn inbox from a specific sender,
with a subject line, a body, an optional banner image, and a single
call-to-action button. It is NOT a Conversation Ad — there is no
branching step graph. Use create_update_convo_ad for multi-step convos.
IMPORTANT: This tool is ONLY for LinkedIn Sponsored Messaging
(channelType=LINKEDIN, adType=MESSAGE). For IMAGE/GIF ads use
create_update_image_ad; for VIDEO ads use create_update_video_ad; for CONVO
use create_update_convo_ad; for Google Ads text ads use
create_update_google_ads_ad; for DOCUMENT ads use
create_update_document_ad. SPOTLIGHT / CTV / FOLLOWER are not yet
covered by the dedicated tools.
BEHAVIOR:
- If `id` is NOT provided → creates a new Message Ad.
- If `id` IS provided → updates the existing Message Ad with that ID.
PREREQUISITES (MUST DO BEFORE CALLING):
1. Call get_linkedin_senders to fetch a valid (senderId, senderName) pair.
Message Ads share LinkedIn's sponsored-messaging sender allow-list
with Conversation Ads — both pull from the same endpoint. Do NOT
invent sender IDs.
2. If using a banner image: upload it via upload_image_creative and
pass the returned imageLibraryId as `bannerCreativeLibraryId`. The
banner is OPTIONAL — omit the field to skip it. LinkedIn requires
an IMAGE creative ≤ 2 MB; oversize banners are rejected upstream.
CHARACTER LIMITS (enforced by the platform; mirror the UI validator at
metadata-ui-v3/.../li/message/edit/validation.ts):
- name ≤ 50 chars (ad name in the library)
- headlineText ≤ 60 chars (the message subject line)
- messageText ≤ 2000 chars (the message body)
- actionText ≤ 20 chars (the CTA button label)
PERSONALIZATION MACROS IN messageText:
The body supports LinkedIn personalization macros. Pass them verbatim
inside `%...%` — the platform substitutes at send time. The validator
accepts ONLY these five macros (any other %...% token is rejected):
%FIRSTNAME%
%LASTNAME%
%COMPANYNAME%
%JOBTITLE%
%INDUSTRY%
Do not use `{firstName}` or any other syntax — only `%MACRO%`.
USAGE INSTRUCTIONS FOR LLM:
Use this tool when users want to:
- Create a new LinkedIn Sponsored Message ad
- Update an existing Message Ad (subject, body, CTA, sender, or banner)
WHEN TO USE:
- User asks "create a LinkedIn Message Ad" / "InMail ad" /
"Sponsored Messaging ad"
- User wants a one-shot LinkedIn DM with subject + body + CTA
- User wants to update an existing Message Ad
WHEN NOT TO USE:
- User wants a branching conversation flow → use create_update_convo_ad
- User wants a feed image / GIF ad → use create_update_image_ad
- User wants a feed video ad → use create_update_video_ad
- User wants a Google Ads text ad → use create_update_google_ads_ad
INPUT PARAMETERS:
- id (optional): Existing Message Ad ID. Provide to UPDATE; omit to
CREATE.
- name (required, ≤ 50): Ad name in the library.
- senderId (required): LinkedIn sender ID from get_linkedin_senders.
- senderName (required): Display name matching senderId.
- headlineText (required, ≤ 60): Subject line shown in the inbox.
- messageText (required, ≤ 2000): Message body. Supports the five
%MACRO% tokens listed above.
- actionText (required, ≤ 20): CTA button label.
- bannerCreativeLibraryId (optional): imageLibraryId of the banner
image. Upload first via upload_image_creative. Omit to skip the
banner.
- completionStatus (optional, default DRAFT): "DRAFT" or "COMPLETED".
Use COMPLETED only when every required field is final.
EXAMPLE USAGE (Create):
create_update_linkedin_message_ad(
name="Q1_Demo_Outreach_LI_Message",
senderId="fQdRPtecbv",
senderName="Josh Desmarais",
headlineText="Quick question about your marketing stack",
messageText="Hi %FIRSTNAME%, as a %JOBTITLE% at %COMPANYNAME% you know how hard pipeline attribution is. Want a 15-min walkthrough?",
actionText="Book a demo",
bannerCreativeLibraryId=482931,
)
EXAMPLE USAGE (Update):
create_update_linkedin_message_ad(
id=29144,
name="Q1_Demo_Outreach_LI_Message_v2",
senderId="fQdRPtecbv",
senderName="Josh Desmarais",
headlineText="Following up — quick demo?",
messageText="Hi %FIRSTNAME%, circling back…",
actionText="Book a demo",
)
SUCCESS RESPONSE (mirrors create_update_convo_ad):
{
"success": true,
"id": 29144,
"ad_url": "https://platform.metadata.io/hub/library/ads?adId=29144",
"name": "Q1_Demo_Outreach_LI_Message",
"channelType": "LINKEDIN",
"adType": "MESSAGE",
"completionStatus": "DRAFT",
"request": { "message": { ... } }
}
COMMON MISTAKES:
❌ Inventing a senderId — IDs MUST come from get_linkedin_senders.
❌ Passing a banner URL instead of an imageLibraryId — upload first.
❌ Using `{firstName}`-style macros — LinkedIn uses `%FIRSTNAME%`.
❌ Using an unsupported macro (anything outside the five listed) —
the platform/UI validator rejects it.
❌ Using this tool for a multi-step flow — use create_update_convo_ad.Arguments
| Argument | Type | Notes | |
|---|---|---|---|
id |
integer | Existing Message Ad ID — include to UPDATE; omit to CREATE. | |
name |
string | required | Ad name in the platform library (max 50 characters). |
senderId |
string | required | LinkedIn sender ID. MUST come from get_linkedin_senders. Do not invent. |
senderName |
string | required | Display name matching senderId, also from get_linkedin_senders. |
headlineText |
string | required | Message subject line shown in the recipient's inbox (max 60 characters). |
messageText |
string | required | Message body (max 2000 characters). Supports LinkedIn personalization macros — ONLY %FIRSTNAME%, %LASTNAME%, %COMPANYNAME%, %JOBTITLE%, %INDUSTRY%. Any other %...% token is rejected by the platform validator. |
actionText |
string | required | Call-to-action button label (max 20 characters). |
bannerCreativeLibraryId |
integer | Optional: imageLibraryId of the banner image shown above the message. Upload the image first via upload_image_creative and pass the returned ID. Omit to skip the banner. | |
completionStatus |
string | Defaults to DRAFT. Use COMPLETED only when every required field is final. one of: DRAFT, COMPLETED |
Request
curl
curl -s -X POST https://mcp-server.metadata.io/mcp \
-H "Authorization: $METADATA_PAT" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "MCP-Protocol-Version: 2025-11-25" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"create_update_linkedin_message_ad","arguments":{"name":"<name>","senderId":"<senderId>","senderName":"<senderName>","headlineText":"<headlineText>","messageText":"<messageText>","actionText":"<actionText>"}}}'
Response
No recorded response. This tool can delete, archive, launch or move budget, so it is never executed to build these docs.
The request above is still the exact shape to send. Nothing on this page is invented.
Related
Other creative tools: