LinkedIn Ads Weekly — optimise-and-report cycle
SkillSecurityRuns a weekly optimise-and-report cycle on a LinkedIn Ads account. Pulls the account (via the read tools of the linkedin-ads MCP, or a pasted export when the API is not authenticated), runs ten optimisation levers split by the data volume each needs, proposes a ranked change list, and — once LinkedIn Ads writes are enabled — applies what the operator approves through the gated linkedin-ads MCP; until then it emits an operator-applies-manually change list. Reporting reuses /paid-ads-report (the WoW dashboard) and /paid-ads-experiment-log (the change journal) rather than re-implementing them. Levers: audience drift, budget pacing, creative fatigue, cost discipline, lead-form health, structure drift (weekly); creative performance, audience saturation, angle refresh, objective/bid fit (28-day). Every write is gated by linkedin-ads-spend.md. Triggers: "LinkedIn Ads weekly", "run the LinkedIn optimisation", "weekly paid social update", "pause underperforming LinkedIn ads". NOT for Google (use /google-ads-weekly), one-off account audits (/paid-ads-audit), the read-only report (/paid-ads-report), or writing ad copy (/linkedin-ads-copy).
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the LinkedIn Ads Weekly — optimise-and-report cycle skill
What this skill tells your AI
The instructions your AI receives, as published by matteotitta/genesys-skills in skills/primitives/paid-marketing/execution/linkedin-ads-weekly/SKILL.md and read by ahel’s review.
Reads a LinkedIn Ads account, proposes a ranked change list, applies what is approved, and drafts the weekly client update. The Google sibling is /google-ads-weekly; this is the same optimise-first-report-second discipline for LinkedIn. The report describes what changed, not just what happened.
Doctrine inherited
linkedin-ads-spend.mdgates every write. Preview before mutate, confirm before spend or delete, never auto-confirm in batch, default to DRAFT/PAUSE. Where LinkedIn Ads writes are not yet enabled (pending Advertising-API / Developer-Portal approval), Phase 3 emits an operator-applies-manually change list and the gate activates once writes land. Non-negotiable when they do.pii-redaction.mdapplies to lead-gen form data, which carries names, work emails and job titles people submitted directly.output-simplicity.mdcaps the Slack update. One screen for a senior reader, not a metrics dump.
When to use
Use it for the weekly cycle on a live LinkedIn Ads account where you hold at least read access.
Do not use it for:
- Google Ads →
/google-ads-weekly - A one-off, deep account audit →
/paid-ads-audit - The read-only week-over-week report on its own →
/paid-ads-report(this skill invokes it in Phase 4) - The standalone change journal →
/paid-ads-experiment-log(also invoked in Phase 4) - Writing or refreshing ad copy →
/linkedin-ads-copy
Inputs
| Input | Required | Notes |
|---|---|---|
| Client slug | yes | Resolves the workflow binding, e.g. ClientCo |
| Account data | yes | Either the linkedin-ads MCP read tools, or a pasted/CSV export. Both are first-class. |
| Client workflow file | recommended | {client}/workflows/linkedin-ads-weekly.md carries the account's targets, campaign split and Slack format |
| Campaign strategy | recommended | The intended structure, so the cycle can detect drift, plus the persona + awareness tiers the angle matrix reads |
The export path is not a fallback. While the API is not authenticated, or access is read-only, or writes are not yet enabled, the cycle runs identically off a pasted export and simply produces a manual-apply change list in Phase 3.
Process
Phase 0 — Ground
Read the client workflow file, the paid strategy doc, and goals/ for targets. Establish: the conversion action being optimised for (lead-gen form completion vs website conversion), the monthly budget, the intended campaign structure (a small set of campaigns spanning use-case, awareness, case-study and retargeting), and the reporting bar. Never invent a target. If it is an unfilled placeholder, say so in the output rather than substituting a benchmark.
Phase 1 — Pull
Run the read tools in the premium reference against the linkedin-ads MCP, or parse the pasted export. Persist the raw pull to the client's paid/execution/ and keep only a summary in context, per context-management.md.
Redact PII from lead-gen form data before it is stored or shared.
Phase 2 — Propose
Run the ten levers in the premium reference. For each finding, produce: the lever, the evidence, the proposed change, the tier it falls in under linkedin-ads-spend.md, and the volume behind it. Rank by expected impact on cost per result.
State the floor next to every verdict. A creative with 300 impressions and no conversion is not a loser, it is unmeasured. Say that rather than proposing a pause.
Output the change list and stop. The operator approves before anything applies.
Phase 3 — Apply
Only after approval, and only for approved items.
- While writes are not yet enabled: emit the approved changes as an operator-applies-manually list — the exact Campaign-Manager steps to take — and log each to the change journal via
/paid-ads-experiment-log. Nothing is written through the API. - When writes land: follow the gate — spend-reducing items (pause a fatigued creative, lower a bid or budget) may share one approval after being itemised; spend-increasing items (raise a budget, activate a campaign) are confirmed individually; deletes are refused. Create as DRAFT/PAUSED. After the batch, re-read the affected resources through the read tools and confirm each change landed. Report anything that did not.
Skip this phase entirely when running from an export.
Phase 4 — Report
Reuse, do not re-implement:
- The WoW dashboard — invoke
/paid-ads-reportfor the client's week-over-week LinkedIn Ads report (it owns the dashboard render + auto-insight opener). This cycle supplies the window; the report skill owns the rest. - The change journal — log each applied (or manually-applied) change via
/paid-ads-experiment-logwith its hypothesis + expected metric, so next cycle can read the lift. - The Slack update — in the client's format. One screen. What changed, what it means, what needs a decision.
- The cycle record — at
{client}/paid/execution/MMYY-NN-linkedin-ads-cycle.md: the pull summary, the full change list with approved/rejected status, what was applied (or listed for manual apply) and verified, and the hypothesis for next week.
Then append a run entry to the client's history.md and refresh latest.md.
Nothing posts to a client channel unprompted. The Slack update is a draft for review.
Known limitations
State these rather than working around them:
- Writes may not be enabled until a LinkedIn Developer App is approved for the Advertising API. Reads work; Phase 3 is manual-apply until then.
- Competitor share is not in the API. LinkedIn has no auction-insights equivalent. The competitor read is a separate
/linkedin-ad-teardownrun against the public Ad Library, and it feeds lever 9, not a query here. - High CPMs, thin volume. At £1,500/mo a week is a handful of leads. Most kill decisions sit below the floor weekly — that is the whole reason for the split.
- Reporting lag + sampling. Recent days under-report; demographic breakdowns are sampled. Never conclude from the last 2 days, and compare like windows.
- Frequency is derived. LinkedIn does not expose frequency directly — compute it as
impressions ÷ approximateUniqueImpressions.
Anti-patterns
- ❌ Proposing a creative pause below the impression floor. That is optimising noise.
- ❌ Reporting a cost-per-lead verdict for a single week on a small account without its floor stated.
- ❌ Re-implementing the WoW dashboard or the change journal inline. Invoke
/paid-ads-reportand/paid-ads-experiment-log. - ❌ Bundling a budget increase into a soft-tier creative-pause approval.
- ❌ Treating a blocked write as a data problem. It is an auth state; run manual-apply and log it.
- ❌ Reallocating an entire budget off one week of demographic data.
- ❌ Posting the Slack update without the operator seeing it.
- ❌ Substituting an industry benchmark when the client's own target is missing. Flag the gap.
Final ship gate
Run /premortem --output before ship. See /premortem skill for the 5 execution domains and output template.
For the Slack update specifically, also run the output-simplicity.md §10 pre-ship check: right length for a senior reader, no robot tells, sources placed correctly for a client-team artifact.
Signals
- GitHub stars
- 36
- Forks
- 14
- Last commit
- Jul 2026
Advanced
- Catalog kind
- skill
- Gateway key
linkedin-ads-weekly- Source
- github.com/matteotitta/genesys-skills