| name | linkedin-auto-optimize |
| description | Run a full LinkedIn ad account health cycle: pacing on lifetime budgets, structural issues (billing/group holds, no-creative campaigns, dormant campaigns), delivery vs budget gaps, and a prioritized action list across audiences, creatives, and structure. Combines lightweight versions of audience-health, creative-fatigue, and bid-sanity checks into a single account-level dashboard. Use when the user says 'optimize my LinkedIn account', 'LinkedIn health check', 'audit my LinkedIn ads', 'why is my LinkedIn spend low', 'why isn't my LinkedIn delivering', 'LinkedIn account review', 'is anything broken on LinkedIn', or 'weekly LinkedIn check-in'. Use as the FIRST skill in any LinkedIn troubleshooting session โ it surfaces what's structurally broken before you dig into specific layers. |
LinkedIn Auto-Optimize (Account Health Cycle)
You produce a single-page account-health read of a LinkedIn ad account, surfacing the structural and pacing issues that block delivery, and routing to deeper-dive skills for specifics.
This skill exists because most LinkedIn delivery problems are structural โ a billing hold, a campaign with no creatives, a lifetime-budget campaign that's already overspent, an audience-count-hold quietly blocking 80% of intended delivery. Marketers tend to debug from the creative layer downward (CTR, copy, audience). The right debug order is the opposite: structure โ audiences โ creatives. This skill enforces that order.
Auto-optimize is the first skill to run in any LinkedIn troubleshooting session. The deeper-dive skills assume the account is structurally healthy; if it isn't, their outputs are misleading.
What the skill produces
A single-page health report with these sections:
- ๐จ Blocker issues โ anything that's preventing delivery RIGHT NOW. Billing holds, no-creative campaigns, group-status holds, count holds. Sorted by daily budget at stake.
- ๐ Pacing issues โ lifetime-budget campaigns that are burning too fast or too slow, daily budgets sitting well under their cap (under-delivery), or above their cap (overpacing risk).
- ๐ก Structure hygiene โ campaigns in PENDING_DELETION still appearing in reports, dormant ACTIVE campaigns (no impressions for 7+ days), campaigns with creatives in REJECTED review state.
- Routing list โ which deeper-dive skill to run for each finding (audience-health, creative-fatigue, demographic-deep-dive, frequency-saturation, etc.).
- Account health score โ 0-100 single number derived from the issue count weighted by severity. Includes a one-line headline summary.
Prerequisites
- LinkedIn Ads MCP โ
list_linkedin_campaigns, list_linkedin_creatives, get_linkedin_ad_analytics (CAMPAIGN pivot, recent window).
- Bash/Python.
Inputs
- Account ID. If unknown, list accounts first and confirm.
- Date window for pacing analysis. Default: trailing 30 days for delivery, current lifetime-budget windows for pacing.
Process
Step 1 โ Pull all relevant data
list_linkedin_campaigns(account_id)
list_linkedin_creatives(account_id)
get_linkedin_ad_analytics(account_id, pivot=CAMPAIGN, start=<30d ago>, end=<today>, fields=pivotValues,impressions,clicks,landingPageClicks,costInLocalCurrency)
get_linkedin_ad_analytics(account_id, pivot=CAMPAIGN, start=<7d ago>, end=<today>, fields=pivotValues,impressions,clicks,costInLocalCurrency)
Step 2 โ Classify every campaign
For each campaign, derive its current health state by combining status, servingStatuses, recent-window analytics, and creative presence:
- LIVE-OK: status=ACTIVE, no holds in servingStatuses, has โฅ1 isServing creative, has impressions in last 7d
- LIVE-DORMANT: status=ACTIVE, no holds, has creatives, but zero impressions in last 7d
- BLOCKED-BILLING: BILLING_HOLD in any serving status
- BLOCKED-GROUP: CAMPAIGN_GROUP_STATUS_HOLD in any serving status
- BLOCKED-AUDIENCE: AUDIENCE_COUNT_HOLD or CAMPAIGN_AUDIENCE_COUNT_HOLD
- BLOCKED-NO-CREATIVES: status=ACTIVE but zero serving creatives (all paused/rejected/removed)
- BLOCKED-REJECTED: status=ACTIVE but all creatives in REJECTED review status
- PAUSED: status=PAUSED (informational only โ not a blocker)
- PENDING-DELETION: status=PENDING_DELETION (cleanup candidate)
Multiple blockers can apply; record all of them.
Step 3 โ Pacing analysis
For each LIVE campaign, compute:
- Delivery rate =
recent_7d_cost / (daily_budget ร 7). Healthy = 0.85-1.15. Below 0.85 = under-pacing (delivery problem). Above 1.15 = over-pacing (budget issue, though LinkedIn rarely lets this happen).
- For LIFETIME-pacing campaigns: if you can see
runSchedule.start and the campaign uses lifetime budget, compute days remaining and project end-spend. Flag campaigns that will overspend or substantially underspend their lifetime budget at current pace.
Flag under-pacing campaigns specifically โ they're the silent failure mode. A campaign budgeted at $150/day but pacing $40/day is leaving 73% of intended delivery on the table.
Step 4 โ Structural hygiene
Flag:
- Dormant ACTIVE campaigns โ
status=ACTIVE but zero impressions in the last 7 days, with creatives that exist. Either count-hold (handled in audience-health) or some other delivery block.
- Campaigns with no serving creatives โ
status=ACTIVE but every creative under it is isServing=false or intendedStatus=PAUSED. Surface the campaign and tell the user to either add creatives or pause the campaign.
- Pending-deletion campaigns still in serving lists โ
status=PENDING_DELETION but appearing in recent analytics. Likely served briefly then was canceled. Cleanup candidate.
- Campaigns with rejected creatives โ Look at the creative-level
review.status field. Any creatives in REVIEW_FAILED or REJECTED block delivery.
Step 5 โ Build the prioritized action list
Rank issues by severity ร dollar impact:
- Severity 5 (Blocker): Billing hold, group hold, audience count hold, no-creative โ daily budget ร 1.0 weighting
- Severity 4 (Under-delivery): Live but pacing <50% of daily budget โ daily budget ร delivery shortfall
- Severity 3 (Pacing risk): Lifetime campaign projected to underspend by โฅ20% โ projected dollar loss
- Severity 2 (Hygiene): Dormant ACTIVE, pending-deletion drift, rejected creatives โ daily budget ร 0.3
- Severity 1 (Informational): Paused campaigns, campaigns with empty creative names โ minor
Step 6 โ Compute account health score
score = max(0, 100 - sum(severity ร 2 for each issue))
Cap at 0 floor, 100 ceiling. Round to nearest 5. Then map to a label:
- 85-100 โ Healthy
- 70-84 โ Minor issues
- 50-69 โ Several issues, needs attention
- 30-49 โ Multiple blockers
- 0-29 โ Account is largely broken; immediate intervention needed
Step 7 โ Produce the report
In order:
# LinkedIn Auto-Optimize โ [Account name]
**Health score: [N]/100 โ [label]**
**Total daily budget on active campaigns:** $X
**Estimated daily budget actually delivering:** $Y ([Y/X]% utilization)
**Number of campaigns: [active], [paused], [pending deletion]**
## ๐จ Blockers (resolve first)
[list, sorted by daily budget at stake]
## ๐ Pacing issues
[list]
## ๐ก Structure hygiene
[list]
## Routing โ next skills to run
- If you have blockers in the count-hold category โ run `linkedin-audience-health-check` for the full audit
- If you have creative-rejection blockers โ check each rejected creative's reason in Campaign Manager
- If you have pacing issues with high spend on a campaign โ run `linkedin-creative-fatigue-watchdog` next
- If overall delivery looks healthy but you want to find waste โ run `linkedin-demographic-deep-dive`
## Headline
[one-line summary of the account's state]
What this skill is NOT
This is not the place to do deep audience overlap detection, creative refresh recommendations, demographic drift analysis, or MMM-style ROI reconciliation. Those have dedicated skills. Auto-optimize is the pre-flight checklist that tells you whether the deeper analyses are worth running.
If everything is structurally fine โ score โฅ 85 โ surface that explicitly. "No structural issues โ proceed to demographic deep dive and creative refresh review for performance optimization."
When to run it
- As the first check when someone says "is something wrong with my LinkedIn ads?"
- Weekly, automated via the Cowork schedule tool โ perfect Monday-morning health check.
- After making structural changes (adding campaigns, changing audiences, refreshing creatives) โ confirm nothing was broken inadvertently.