campaign-workflow — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited campaign-workflow (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Orchestrate a complete GAM campaign from scratch to live delivery. This skill chains sub-skills in the correct order, enforces GAM best practices, and ensures nothing is skipped.
Every campaign in Google Ad Manager follows this strict hierarchy. Each entity depends on its parent existing first.
Network
└── Company (Advertiser)
└── Order
└── Line Item
├── Inventory Targeting (ad units or placements)
├── Audience Targeting (geo, device, key-values)
├── Creative Placeholders (expected sizes)
└── Creative Assignments (LICAs)
└── Creative (image, native, video...)Rule: you cannot skip levels. A Line Item requires an Order. An Order requires an Advertiser. A Creative Assignment requires both a Line Item and a Creative with matching sizes.
The user may have configured naming conventions, delivery defaults, campaign presets, and tenant settings. Always read these before creating any entity. The configuration is tenant-level and applies to all campaigns.
get_naming_conventions)Templates with macros that control how entities are named:
orderTemplate: e.g. {YYYY}{MM}-{advertiser}-{campaign}lineItemTemplate: e.g. {order}-{format}-{placement}creativeTemplate: e.g. {advertiser}-{format}-{size}nativeStyleTemplate: e.g. {advertiser}-NS-{format}reportNameTemplate: e.g. {report_type}-{YYYY}{MM}{DD}-{date_range}Available macros: {YYYY}, {MM}, {DD}, {advertiser}, {campaign}, {order}, {type}, {format}, {size}, {placement}, {name}, {start_YYYY}, {start_MM}, {start_DD}, {end_YYYY}, {end_MM}, {end_DD}
When a template is null, GAM auto-generates the name.
get_delivery_defaults)Tenant-level defaults applied when creating line items:
lineItemType, deliveryRateType, creativeRotationTypecostType, currencyCode, microAmount (CPM in micros, 1000000 = 1.00)priority, frequencyCapImpressions, frequencyCapPeriodroadblockingType, timeZoneIdstartDateTimeType (IMMEDIATELY or ONE_HOUR_FROM_NOW)unlimitedEndDateTime (boolean)list_presets)Pre-configured ad unit + targeting combos:
__builtin_homepage — Pack Homepage__builtin_ros — Pack Run of Site__builtin_interstitiel — Pack Interstitielget_tenant_settings)autoArchivalEnabled + archivalDelayDaysga4PropertyId (for GA4 reports)previewPages (for in-context preview URLs)If get_naming_conventions returns null templates (user has not configured naming), use these defaults:
| Entity | Default Pattern | Example |
|---|---|---|
| Advertiser | {BrandName} | Renault |
| Order | {BrandName} — {Campaign} — {Month YYYY} | Renault — Spring Launch — Apr 2026 |
| Line Item | {BrandName} — {Format} — {Targeting} — {Type} | Renault — MPU 300x250 — FR Desktop — Standard |
| Creative | {BrandName} — {Format} — {Version} | Renault — MPU 300x250 — v1 |
| Placement | {SiteName} — {Section} — {Position} | LeMonde — Homepage — Leaderboard |
Rules:
— (em dash) as separator, not - (hyphen)Pre-condition: Active network with confirmed tenantId and networkCode.
If not confirmed, run /orbiads:bootstrap first.
Read tenant configuration — call these MCP tools before any entity creation:
get_naming_conventions — understand how the user wants entities namedget_delivery_defaults — understand the user's default line item settings (type, CPM, pacing, etc.)list_presets — check if pre-configured campaign presets exist (may skip manual inventory discovery)get_tenant_settings — read archival settings, GA4 property, and preview pagesStore the results for use in subsequent phases. If any call fails, proceed with the fallback defaults documented above.
Goal: Identify where the ads will serve and what targeting to apply.
Check presets first. If list_presets returned presets that match the campaign brief (e.g., user wants a homepage takeover and __builtin_homepage exists), use the preset's adUnitIds and keyValues directly. This skips manual ad unit discovery.
If no preset matches, proceed with manual discovery:
list_ad_units, search_ad_units, get_ad_unit_treeorbiads inventory ad-units --json or --search "<name>"list_placementsorbiads inventory placements --jsonlist_custom_targeting_keys, get_custom_targeting_valuesorbiads inventory keys --jsonvalidate_fluidOutput: List of adUnitIds, available sizes, targeting keys. Pass to Phase 2.
Goal: Verify enough inventory exists before committing to a campaign.
get_standalone_forecast or get_delivery_forecast_by_line_itemorbiads reporting run --type forecast --ad-units <ids> --start <date> --end <date> --jsonavailableUnits > campaign goal — safe to proceedavailableUnits between 50-100% of goal — proceed with caution, may need broader targetingavailableUnits < 50% of goal — stop and adjust (broader targeting, more ad units, or lower goal)GAM best practice: Always forecast before creating line items. A forecast is free and prevents overbooking.
Output: Forecast summary with go/adjust/stop recommendation. Pass to Phase 3.
Goal: Create or resolve the advertiser and order that will contain the line items.
find_or_create_advertiserorbiads advertisers list --search "<name>" --json, then orbiads advertisers create --name "<name>" --json if not foundadvertiserId on an Order must point to a Company with type=ADVERTISER. Using an agency ID causes an error.orderTemplate from get_naming_conventions if configured. Provide the macro values (advertiser name, campaign name, dates) and the backend will expand the template. If no template is configured, use the fallback pattern: {Brand} — {Campaign} — {Month YYYY}traffickerId to the user's GAM user IDcreate_order (within advertiser-order-line-items tools)orbiads orders create --advertiser <id> --name "<name>" --jsonOutput: Confirmed advertiserId and orderId. Pass to Phase 4.
Goal: Create line items with correct type, pricing, dates, targeting, and creative placeholders.
Read delivery defaults first. Apply the user's delivery defaults from get_delivery_defaults (loaded in Phase 0). The user may have configured custom line item type, CPM rate, pacing, frequency caps, etc. Only override these defaults when the campaign brief explicitly specifies different values.
lineItemType if not specified in the brief):| Campaign goal | Line Item Type | Priority |
|---|---|---|
| Guaranteed impressions (direct sold) | STANDARD | 6-10 |
| Share of voice / takeover | SPONSORSHIP | 4 |
| Backfill / remnant | PRICE_PRIORITY | 12 |
| Self-promotional | HOUSE | 16 |
| Ad network / exchange | NETWORK | 12 |
orderId — from Phase 3name — Apply the user's lineItemTemplate from get_naming_conventions if configured. Provide macro values (order name, format, placement, size). If no template is configured, use the fallback pattern: {Brand} — {Size} — {Targeting} — {Type}startDateTime / endDateTime — must match the campaign brief. Use the user's timeZoneId from delivery defaults (or network timezone).costType + costPerUnit — Use the user's default costType and microAmount from delivery defaults. CPM requires unitType=IMPRESSIONS, CPC requires unitType=CLICKS. Override only if the brief specifies a different rate.primaryGoal — impression or click goalcreativePlaceholders — list of expected sizes (e.g., 300x250, 728x90). Must match creative sizes exactly.targeting.inventoryTargeting — at least one ad unit or placement. Mandatory.creativeRotationType — Use the user's default from delivery defaults (typically OPTIMIZED). Override with EVEN for explicit A/B testing.deliveryRateType: Use the user's default from delivery defaults. Common values: EVENLY (recommended), FRONTLOADED (launch events), AS_FAST_AS_POSSIBLE (remnant only)frequencyCaps: Use the user's default frequencyCapImpressions and frequencyCapPeriod. Combine short-term (1/hour) with long-term (10/week) caps if needed.priority: Use the user's default priority from delivery defaults unless the brief requires a different value.roadblockingType: Use the user's default from delivery defaults.keyValuesGAM best practices:
creativePlaceholders — a line item without them gets stuck in NEEDS_CREATIVES state.Output: Created lineItemIds with targeting configured. Pass to Phase 5.
Goal: Create creatives and assign them to line items.
creativePlaceholders sizes:creativeTemplate from get_naming_conventions if configured. Provide macro values (advertiser name, format, size). If no template is configured, use the fallback pattern: {Brand} — {Format} — {Version}create_image_creative, create_classic_native_creativeorbiads creatives upload --file <path> --name "<name>" --advertiser <id> --jsonCreativeAssetService is removed. Image bytes must be inlined in createCreatives.creativePlaceholders. Size mismatch is the #1 API error.associate_creativeNEEDS_CREATIVES to READY.NEEDS_CREATIVES, a size is missing or the assignment failed.Output: Created creativeIds, confirmed assignments. Pass to Phase 6.
Goal: Last quality gate before going live. Never skip this phase.
scan_creative_compliancevalidate_creative_ssl or validate_creative_ssl_batchorbiads creatives get --id <id> --json (check SSL fields)deploy_campaign with dry_run=Trueorbiads campaigns deploy <id> --dry-run --jsoncheck_creative_coverageget_preview_urls or get_campaign_preview_urlspreviewPages from tenant settings (loaded in Phase 0) for in-context preview. If previewPages is configured, the preview URLs will render creatives within the user's actual site pages, giving a realistic view of how ads will appear in production.orderTemplate if set)Decision:
Output: Go/no-go decision with findings. Pass to Phase 7 if GO.
Goal: Push the campaign live and verify delivery.
approve_orderdeploy_campaign (without dry_run)orbiads campaigns deploy <id> --yes --jsoncheck_delivery_status, fetch_delivery_reportorbiads campaigns get <id> --json, orbiads reporting run --type delivery --campaign <id> --jsoncheck_underdelivery_alerts, check_budget_alerts DRAFT → NEEDS_CREATIVES → READY → DELIVERING → COMPLETED
→ PAUSED (manual)
→ DELIVERY_EXTENDED (if pacing behind)A line item stuck in NEEDS_CREATIVES means a creative is missing or size doesn't match.
Output: Deployment confirmed, delivery metrics, any alerts.
| Phase | MCP Skill | CLI Skill |
|---|---|---|
| 0 | /orbiads:bootstrap | /orbiads:cli-bootstrap |
| 1 | /orbiads:inventory-ad-units + /orbiads:placements-targeting | /orbiads:cli-inventory + /orbiads:cli-targeting |
| 2 | /orbiads:availability-forecast | /orbiads:cli-forecast |
| 3-4 | /orbiads:advertiser-order-line-items | /orbiads:cli-orders |
| 5 | /orbiads:native-image | /orbiads:cli-creatives |
| 6 | /orbiads:qa-preview | /orbiads:cli-qa |
| 7 | /orbiads:deploy-reporting | /orbiads:cli-deploy |
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.