Use this skill when building or planning an AI-agent system that manages paid ads (especially Meta/Facebook/Instagram Ads) through Hermes, OpenClaw-style skills, MCPs, official CLIs, or direct marketing APIs.
This is a class-level skill for self-hosted ad-ops agent platforms: chat-first operation, dashboard visibility, local state, approval queues, creative generation, performance reporting, and spend-safety controls.
Alex prefers the build-it-ourselves route over paid opaque SaaS wrappers for ad automation.
Default architecture:
Load this skill when the user asks to:
User chat → Hermes → paid-ads skill/scripts
↓
Local app API/database ←→ Dashboard
↓
Official Ads CLI / Marketing API adapter
↓
Ad platform account hierarchy
Separate responsibilities clearly:
Mirror the ad platform hierarchy locally, then attach richer local workflow state.
Minimum entities:
projects — local apps/products/businesses being marketed.locations — optional physical locations/geos tied to a project.ad_accounts — platform account metadata, not secrets.project_ad_links — maps local projects to ad account/page/pixel/event IDs.campaigns, ad_sets, ads, creatives — local cache of platform hierarchy.drafts — Hermes-created changes awaiting approval.approvals — explicit accept/reject/needs-changes decisions.insight_snapshots — saved performance pulls.monitor_rules — scheduled checks and alert/action rules.audit_events — append-only record of prompts, drafts, approvals, API calls, and errors.Start by proving data access and reporting.
Smoke-test discipline:
.env; verify .env is ignored and never print full tokens.META_ACCESS_TOKEN, set .env to 0600, remove any temporary secret-bearing backup once verification passes, and restart hermes-ads with pm2 restart hermes-ads --update-env.APP_ID|... is usually an app/client token and will not read ad account data. Use a User/System User token with ads_read and read_insights.id,account_id,name,account_status,currency,timezone_name) for the baseline proof. Adding nested business{...} can trigger (#100) Requires business_management permission even when read-only ads reporting works.Do not start with campaign creation.
Build a web app that displays read-only state:
Use Alex's VPS deployment conventions from vps-app-deployment.
Hermes can create local drafts only:
Dashboard approves/rejects drafts; no platform writes yet.
Only approved drafts can call the platform API/CLI.
Separate approval from execution in the UX. A button labeled “Approve” should only record local human approval unless it explicitly says it will push to the ad platform. Use a second, unambiguous action such as Push to Meta as PAUSED for platform writes. After the push, persist returned platform IDs on the draft, change draft status to a pushed state (for example pushed_paused), show the IDs/search hint in the queue, and audit the action. This prevents the user from expecting Ads Manager objects to appear after a purely local approval.
For Meta, create entities in PAUSED status by default where the API/CLI supports it. Treat the first write test as a full hierarchy smoke test: Campaign → Ad Set → Creative → Ad. If Campaign/Ad Set succeeds but Creative/Ad fails, preserve and report the partial success rather than retrying blindly.
Meta paused-write gotchas:
ads_management can successfully create paused Campaigns and Ad Sets while still being blocked at Creative/Ad creation.adcreatives fails with (#100) Ads creative post was created by an app that is in development mode... / subcode 1885183, the fix is to switch the Meta Developer App from Development to Live/Public mode before retrying.pages_read_engagement; Page access failures can appear as Object does not exist... even when the ID is correct.TEST + timestamp names and tiny budgets (for example $5/day) for smoke tests so Alex can find the objects in Ads Manager and verify they are paused.Add scheduled checks:
Default action is alert-only. Auto-actions require explicit configuration and tight caps.
Make creative generation project-aware:
Prefer these credentials for read-only MVP:
META_ACCESS_TOKENMETA_AD_ACCOUNT_ID with act_ prefixads_read and read_insightsWrite mode later needs ads_management and often page/pixel/business context.
Important Meta hierarchy:
Business Manager
Ad Account
Campaign
Ad Set
Ad
Creative
Reporting metrics to normalize:
Diagnosis concepts to include in references:
Default blocked or confirmation-required actions:
Default allowed actions:
When a request implies spend or platform mutation, require exact target identity and explicit approval. Log every action.
A Hermes ad-operator skill should include:
meta-ads-operator/
├── SKILL.md
├── scripts/
│ ├── meta_adapter.py
│ ├── report.py
│ ├── diagnose.py
│ ├── draft_campaign.py
│ └── execute_approved.py
├── references/
│ ├── safety-policy.md
│ ├── reporting-metrics.md
│ ├── meta-diagnosis-framework.md
│ └── creative-brief-framework.md
└── templates/
├── daily-report.md
├── campaign-draft.json
└── creative-brief.md
Scripts should output JSON so Hermes can summarize reliably.
Recommended screens:
For Alex, make the dashboard mobile-first and single-column by default. Chat remains the primary control surface.
Approval queue UX for ads:
references/hermes-ads-planning.md for the Hermes Ads planning repo, session decisions, and public-skill inspiration notes.references/hermes-ads-wizard-launch.md for the first deployed internal Meta hookup wizard, live URL/PM2 details, and launch-specific deployment quirks.references/hermes-ads-hookup-wizard.md for the internal Meta hookup wizard pattern: Astral-style onboarding, official Meta links, checklist progress, safe .env template generation, PWA details, and deployment verification gotchas.references/hermes-ads-dashboard-mvp.md for the first deployed dashboard MVP pattern: SQLite persistence, Meta sync/report endpoints, mobile cockpit tabs, local draft/approval queue, audit events, verification commands, and the safety boundary before ads_management writes.references/meta-readonly-smoke-test.md for the safe token-handling and minimal Meta read-only smoke-test pattern, including app-token vs user/system-user token behavior and avoiding business_management-only fields.references/meta-paused-write-smoke-test.md for the first safe Meta write pattern: paused Campaign → paused Ad Set → Creative/Ad, partial-success reporting, Development Mode creative blocker (1885183), Live/Published-mode success, bid-strategy gotchas, public legal URL setup, and pages_read_engagement page-access pitfalls.references/meta-system-user-token-rotation.md for the safe Hermes Ads token update pattern: compare redacted fingerprints, update META_ACCESS_TOKEN, chmod .env to 0600, avoid secret backups, restart PM2 with --update-env, and verify with scripts/meta_readonly_smoke.py.references/hermes-ads-paused-draft-push.md for the dashboard-driven approved-draft push pattern: separate local approval from Push to Meta as PAUSED, persist Meta IDs back onto drafts, audit failures/partial IDs, and keep approval queue cards compact rather than visually bloated.references/openclaw-meta-ads-comparison.md for ClawHub/OpenClaw Meta Ads skill notes: the original meta-ads-open-cli is read-only, OpenClaw's posture is analyze-first/recommend-second/change-last, and Meta App Review should position Hermes Ads as an internal human-approved dashboard that creates paused entities only.When Alex asks for a setup/onboarding wizard for Meta Ads hookup, build a guide-first internal tool before full OAuth or write automation:
act_... Ad Account ID, Page ID, Instagram account ID, pixel/dataset ID, and Meta App ID..env template but warn that real access tokens belong only in an uncommitted VPS .env, not Git, logs, screenshots, or browser localStorage.ads_read, read_insights). ads_management remains later, explicit-approval-gated write mode.