dreamcontext 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +523 -0
- package/agents/dreamcontext-explore.md +137 -0
- package/agents/dreamcontext-initializer.md +169 -0
- package/agents/sleep-product.md +268 -0
- package/agents/sleep-state.md +270 -0
- package/agents/sleep-tasks.md +134 -0
- package/dist/agents/dreamcontext-explore.md +137 -0
- package/dist/agents/dreamcontext-initializer.md +169 -0
- package/dist/agents/sleep-product.md +268 -0
- package/dist/agents/sleep-state.md +270 -0
- package/dist/agents/sleep-tasks.md +134 -0
- package/dist/dashboard/assets/BrainCanvas3D-BLJ4_SqE.js +5126 -0
- package/dist/dashboard/assets/_baseUniq-DpaDAx_H.js +1 -0
- package/dist/dashboard/assets/arc-JvK3Ik1p.js +1 -0
- package/dist/dashboard/assets/architectureDiagram-Q4EWVU46-CCvw4XFg.js +36 -0
- package/dist/dashboard/assets/blockDiagram-DXYQGD6D-DMobz1n7.js +132 -0
- package/dist/dashboard/assets/c4Diagram-AHTNJAMY-FwcHT5er.js +10 -0
- package/dist/dashboard/assets/channel-D6954IHZ.js +1 -0
- package/dist/dashboard/assets/chunk-4BX2VUAB-B5kYwmBa.js +1 -0
- package/dist/dashboard/assets/chunk-4TB4RGXK-0ot1eS0J.js +206 -0
- package/dist/dashboard/assets/chunk-55IACEB6-24ngcLgH.js +1 -0
- package/dist/dashboard/assets/chunk-EDXVE4YY-DATt1OUl.js +1 -0
- package/dist/dashboard/assets/chunk-FMBD7UC4-BprbGSJw.js +15 -0
- package/dist/dashboard/assets/chunk-OYMX7WX6-CJJhpKWP.js +231 -0
- package/dist/dashboard/assets/chunk-QZHKN3VN-Cisp65Vq.js +1 -0
- package/dist/dashboard/assets/chunk-YZCP3GAM-DtMk33tU.js +1 -0
- package/dist/dashboard/assets/classDiagram-6PBFFD2Q-Bk4KDqBj.js +1 -0
- package/dist/dashboard/assets/classDiagram-v2-HSJHXN6E-Bk4KDqBj.js +1 -0
- package/dist/dashboard/assets/clone-C9Yhti5q.js +1 -0
- package/dist/dashboard/assets/cose-bilkent-S5V4N54A-BxYomDLe.js +1 -0
- package/dist/dashboard/assets/cytoscape.esm-D_LviqZs.js +331 -0
- package/dist/dashboard/assets/dagre-KV5264BT-CsX1ZayG.js +4 -0
- package/dist/dashboard/assets/defaultLocale-DX6XiGOO.js +1 -0
- package/dist/dashboard/assets/diagram-5BDNPKRD-B2G4mPPw.js +10 -0
- package/dist/dashboard/assets/diagram-G4DWMVQ6-C8nxN9ZB.js +24 -0
- package/dist/dashboard/assets/diagram-MMDJMWI5-DaYymOrR.js +43 -0
- package/dist/dashboard/assets/diagram-TYMM5635-BpiYFv-I.js +24 -0
- package/dist/dashboard/assets/erDiagram-SMLLAGMA-C6pE7F61.js +85 -0
- package/dist/dashboard/assets/flowDiagram-DWJPFMVM-jdNEPVFq.js +162 -0
- package/dist/dashboard/assets/ganttDiagram-T4ZO3ILL-C8GoRj1C.js +292 -0
- package/dist/dashboard/assets/gitGraphDiagram-UUTBAWPF-SiRn7RJ8.js +106 -0
- package/dist/dashboard/assets/graph-9wbTW7ld.js +1 -0
- package/dist/dashboard/assets/index-BHp63EMw.js +475 -0
- package/dist/dashboard/assets/index-CdnDt_7U.css +1 -0
- package/dist/dashboard/assets/infoDiagram-42DDH7IO-DcDC8M1a.js +2 -0
- package/dist/dashboard/assets/ishikawaDiagram-UXIWVN3A-UjyrPeaS.js +70 -0
- package/dist/dashboard/assets/journeyDiagram-VCZTEJTY-CXJPYMxN.js +139 -0
- package/dist/dashboard/assets/kanban-definition-6JOO6SKY-Cm1n9eat.js +89 -0
- package/dist/dashboard/assets/katex-DkKDou_j.js +257 -0
- package/dist/dashboard/assets/layout-w8zmQGXp.js +1 -0
- package/dist/dashboard/assets/linear-CMNvIisH.js +1 -0
- package/dist/dashboard/assets/min-BqXwiqEr.js +1 -0
- package/dist/dashboard/assets/mindmap-definition-QFDTVHPH-tksxnjhx.js +96 -0
- package/dist/dashboard/assets/pieDiagram-DEJITSTG-lIVvnPyq.js +30 -0
- package/dist/dashboard/assets/quadrantDiagram-34T5L4WZ-DSMB57t5.js +7 -0
- package/dist/dashboard/assets/requirementDiagram-MS252O5E-NG99tgmc.js +84 -0
- package/dist/dashboard/assets/sankeyDiagram-XADWPNL6-C6EkbQKo.js +10 -0
- package/dist/dashboard/assets/sequenceDiagram-FGHM5R23-ASU7Zp6_.js +157 -0
- package/dist/dashboard/assets/stateDiagram-FHFEXIEX-DHklUzce.js +1 -0
- package/dist/dashboard/assets/stateDiagram-v2-QKLJ7IA2-BZXFb2Fh.js +1 -0
- package/dist/dashboard/assets/timeline-definition-GMOUNBTQ-B37xNhjS.js +120 -0
- package/dist/dashboard/assets/vennDiagram-DHZGUBPP-D28OvWbm.js +34 -0
- package/dist/dashboard/assets/wardley-RL74JXVD-BQdaLyVb.js +162 -0
- package/dist/dashboard/assets/wardleyDiagram-NUSXRM2D-D0vChrnT.js +20 -0
- package/dist/dashboard/assets/xychartDiagram-5P7HB3ND-BzSx7EpJ.js +7 -0
- package/dist/dashboard/favicon.svg +14 -0
- package/dist/dashboard/index.html +18 -0
- package/dist/hooks/marketing-binary-guard.sh +18 -0
- package/dist/index.js +15881 -0
- package/dist/skill-packs/agents/biv-customer-analyst.md +140 -0
- package/dist/skill-packs/agents/biv-decision-gate.md +147 -0
- package/dist/skill-packs/agents/biv-financial-analyst.md +128 -0
- package/dist/skill-packs/agents/biv-market-analyst.md +103 -0
- package/dist/skill-packs/agents/biv-researcher.md +140 -0
- package/dist/skill-packs/agents/biv-strategist.md +164 -0
- package/dist/skill-packs/agents/council-persona.md +142 -0
- package/dist/skill-packs/agents/council-synthesizer.md +208 -0
- package/dist/skill-packs/agents/discover-brand.md +216 -0
- package/dist/skill-packs/agents/goal-implementer.md +70 -0
- package/dist/skill-packs/agents/goal-plan-reviewer.md +68 -0
- package/dist/skill-packs/agents/goal-planner.md +75 -0
- package/dist/skill-packs/agents/goal-validator.md +68 -0
- package/dist/skill-packs/agents/marketing-creative.md +85 -0
- package/dist/skill-packs/agents/marketing-monitor.md +143 -0
- package/dist/skill-packs/agents/marketing-strategy.md +139 -0
- package/dist/skill-packs/agents/review-cloud-functions.md +158 -0
- package/dist/skill-packs/agents/review-edge-cases.md +147 -0
- package/dist/skill-packs/agents/review-frontend.md +134 -0
- package/dist/skill-packs/agents/review-router.md +165 -0
- package/dist/skill-packs/agents/review-security.md +139 -0
- package/dist/skill-packs/agents/reviewer.md +152 -0
- package/dist/skill-packs/brand-voice/SKILL.md +115 -0
- package/dist/skill-packs/brand-voice/discover-brand.md +126 -0
- package/dist/skill-packs/brand-voice/guideline-generation.md +154 -0
- package/dist/skill-packs/brand-voice/references/before-after-examples.md +194 -0
- package/dist/skill-packs/brand-voice/references/confidence-scoring.md +128 -0
- package/dist/skill-packs/brand-voice/references/guideline-template.md +241 -0
- package/dist/skill-packs/brand-voice/references/search-strategies.md +271 -0
- package/dist/skill-packs/brand-voice/references/source-ranking.md +248 -0
- package/dist/skill-packs/brand-voice/references/voice-constant-tone-flexes.md +115 -0
- package/dist/skill-packs/business-idea-discovery/SKILL.md +452 -0
- package/dist/skill-packs/business-idea-validation/SKILL.md +209 -0
- package/dist/skill-packs/business-idea-validation/stage-definitions.md +658 -0
- package/dist/skill-packs/catalog.json +657 -0
- package/dist/skill-packs/council/SKILL.md +134 -0
- package/dist/skill-packs/council/debate-protocol.md +90 -0
- package/dist/skill-packs/design/SKILL.md +301 -0
- package/dist/skill-packs/design/design-mobile.md +207 -0
- package/dist/skill-packs/design/design-web.md +148 -0
- package/dist/skill-packs/design/frontend-principles.md +157 -0
- package/dist/skill-packs/design/onboarding-design.md +230 -0
- package/dist/skill-packs/engineering/SKILL.md +155 -0
- package/dist/skill-packs/engineering/backend-principles.md +233 -0
- package/dist/skill-packs/engineering/firebase-cloud-functions/SKILL.md +44 -0
- package/dist/skill-packs/engineering/firebase-cloud-functions/references/gen_comparison.md +45 -0
- package/dist/skill-packs/engineering/firebase-cloud-functions/references/idempotency.md +145 -0
- package/dist/skill-packs/engineering/firebase-cloud-functions/references/local_testing.md +218 -0
- package/dist/skill-packs/engineering/firebase-cloud-functions/references/scaling.md +128 -0
- package/dist/skill-packs/engineering/firebase-cloud-functions/references/secrets.md +70 -0
- package/dist/skill-packs/engineering/firebase-cloud-functions/references/triggers_and_deployment.md +139 -0
- package/dist/skill-packs/engineering/firebase-firestore/SKILL.md +50 -0
- package/dist/skill-packs/engineering/firebase-firestore/references/indexes.md +96 -0
- package/dist/skill-packs/engineering/firebase-firestore/references/provisioning.md +101 -0
- package/dist/skill-packs/engineering/firebase-firestore/references/query_mechanics.md +182 -0
- package/dist/skill-packs/engineering/firebase-firestore/references/security_rules.md +299 -0
- package/dist/skill-packs/engineering/firebase-firestore/references/web_sdk_usage.md +265 -0
- package/dist/skill-packs/engineering/web-app-frontend.md +187 -0
- package/dist/skill-packs/goal-skill/SKILL.md +203 -0
- package/dist/skill-packs/growth/SKILL.md +480 -0
- package/dist/skill-packs/growth/lean-analytics-experiments.md +341 -0
- package/dist/skill-packs/growth/lean-analytics-metrics.md +295 -0
- package/dist/skill-packs/growth/performance-marketing.md +337 -0
- package/dist/skill-packs/meta-marketing/SKILL.md +423 -0
- package/dist/skill-packs/meta-marketing/account-ops.md +190 -0
- package/dist/skill-packs/meta-marketing/api-reference.md +535 -0
- package/dist/skill-packs/meta-marketing/copy-formulas.md +123 -0
- package/dist/skill-packs/meta-marketing/council-personas/creative-director.md +76 -0
- package/dist/skill-packs/meta-marketing/council-personas/performance-monitor.md +71 -0
- package/dist/skill-packs/meta-marketing/council-personas/risk-officer.md +79 -0
- package/dist/skill-packs/meta-marketing/council-personas/strategy-optimizer.md +76 -0
- package/dist/skill-packs/meta-marketing/creative-frameworks.md +176 -0
- package/dist/skill-packs/meta-marketing/mistakes.md +154 -0
- package/dist/skill-packs/meta-marketing/platform-state.md +63 -0
- package/dist/skill-packs/multi-review/REVIEWER_SHARED.md +143 -0
- package/dist/skill-packs/multi-review/SKILL.md +182 -0
- package/dist/skill-packs/system-prompts/SKILL.md +472 -0
- package/dist/templates/AGENTS.md +84 -0
- package/dist/templates/CLAUDE.md +84 -0
- package/dist/templates/council-debate.md +20 -0
- package/dist/templates/council-final-report.md +34 -0
- package/dist/templates/council-persona.md +10 -0
- package/dist/templates/council-report.md +6 -0
- package/dist/templates/feature.md +38 -0
- package/dist/templates/init/0.soul.md +33 -0
- package/dist/templates/init/1.user.md +29 -0
- package/dist/templates/init/2.memory.md +21 -0
- package/dist/templates/init/3.style_guide_and_branding.md +18 -0
- package/dist/templates/init/4.tech_stack.md +22 -0
- package/dist/templates/init/CHANGELOG.json +1 -0
- package/dist/templates/init/RELEASES.json +1 -0
- package/dist/templates/init/data-structures/default.md +35 -0
- package/dist/templates/knowledge.md +10 -0
- package/dist/templates/obsidian/app.json +15 -0
- package/dist/templates/obsidian/appearance.json +4 -0
- package/dist/templates/obsidian/graph.json +58 -0
- package/dist/templates/task.md +70 -0
- package/install.sh +73 -0
- package/package.json +58 -0
- package/skill/SKILL.md +529 -0
- package/skill-packs/agents/biv-customer-analyst.md +140 -0
- package/skill-packs/agents/biv-decision-gate.md +147 -0
- package/skill-packs/agents/biv-financial-analyst.md +128 -0
- package/skill-packs/agents/biv-market-analyst.md +103 -0
- package/skill-packs/agents/biv-researcher.md +140 -0
- package/skill-packs/agents/biv-strategist.md +164 -0
- package/skill-packs/agents/council-persona.md +142 -0
- package/skill-packs/agents/council-synthesizer.md +208 -0
- package/skill-packs/agents/discover-brand.md +216 -0
- package/skill-packs/agents/goal-implementer.md +70 -0
- package/skill-packs/agents/goal-plan-reviewer.md +68 -0
- package/skill-packs/agents/goal-planner.md +75 -0
- package/skill-packs/agents/goal-validator.md +68 -0
- package/skill-packs/agents/marketing-creative.md +85 -0
- package/skill-packs/agents/marketing-monitor.md +143 -0
- package/skill-packs/agents/marketing-strategy.md +139 -0
- package/skill-packs/agents/review-cloud-functions.md +158 -0
- package/skill-packs/agents/review-edge-cases.md +147 -0
- package/skill-packs/agents/review-frontend.md +134 -0
- package/skill-packs/agents/review-router.md +165 -0
- package/skill-packs/agents/review-security.md +139 -0
- package/skill-packs/agents/reviewer.md +152 -0
- package/skill-packs/brand-voice/SKILL.md +115 -0
- package/skill-packs/brand-voice/discover-brand.md +126 -0
- package/skill-packs/brand-voice/guideline-generation.md +154 -0
- package/skill-packs/brand-voice/references/before-after-examples.md +194 -0
- package/skill-packs/brand-voice/references/confidence-scoring.md +128 -0
- package/skill-packs/brand-voice/references/guideline-template.md +241 -0
- package/skill-packs/brand-voice/references/search-strategies.md +271 -0
- package/skill-packs/brand-voice/references/source-ranking.md +248 -0
- package/skill-packs/brand-voice/references/voice-constant-tone-flexes.md +115 -0
- package/skill-packs/business-idea-discovery/SKILL.md +452 -0
- package/skill-packs/business-idea-validation/SKILL.md +209 -0
- package/skill-packs/business-idea-validation/stage-definitions.md +658 -0
- package/skill-packs/catalog.json +657 -0
- package/skill-packs/council/SKILL.md +134 -0
- package/skill-packs/council/debate-protocol.md +90 -0
- package/skill-packs/design/SKILL.md +301 -0
- package/skill-packs/design/design-mobile.md +207 -0
- package/skill-packs/design/design-web.md +148 -0
- package/skill-packs/design/frontend-principles.md +157 -0
- package/skill-packs/design/onboarding-design.md +230 -0
- package/skill-packs/engineering/SKILL.md +155 -0
- package/skill-packs/engineering/backend-principles.md +233 -0
- package/skill-packs/engineering/firebase-cloud-functions/SKILL.md +44 -0
- package/skill-packs/engineering/firebase-cloud-functions/references/gen_comparison.md +45 -0
- package/skill-packs/engineering/firebase-cloud-functions/references/idempotency.md +145 -0
- package/skill-packs/engineering/firebase-cloud-functions/references/local_testing.md +218 -0
- package/skill-packs/engineering/firebase-cloud-functions/references/scaling.md +128 -0
- package/skill-packs/engineering/firebase-cloud-functions/references/secrets.md +70 -0
- package/skill-packs/engineering/firebase-cloud-functions/references/triggers_and_deployment.md +139 -0
- package/skill-packs/engineering/firebase-firestore/SKILL.md +50 -0
- package/skill-packs/engineering/firebase-firestore/references/indexes.md +96 -0
- package/skill-packs/engineering/firebase-firestore/references/provisioning.md +101 -0
- package/skill-packs/engineering/firebase-firestore/references/query_mechanics.md +182 -0
- package/skill-packs/engineering/firebase-firestore/references/security_rules.md +299 -0
- package/skill-packs/engineering/firebase-firestore/references/web_sdk_usage.md +265 -0
- package/skill-packs/engineering/web-app-frontend.md +187 -0
- package/skill-packs/goal-skill/SKILL.md +203 -0
- package/skill-packs/growth/SKILL.md +480 -0
- package/skill-packs/growth/lean-analytics-experiments.md +341 -0
- package/skill-packs/growth/lean-analytics-metrics.md +295 -0
- package/skill-packs/growth/performance-marketing.md +337 -0
- package/skill-packs/meta-marketing/SKILL.md +423 -0
- package/skill-packs/meta-marketing/account-ops.md +190 -0
- package/skill-packs/meta-marketing/api-reference.md +535 -0
- package/skill-packs/meta-marketing/copy-formulas.md +123 -0
- package/skill-packs/meta-marketing/council-personas/creative-director.md +76 -0
- package/skill-packs/meta-marketing/council-personas/performance-monitor.md +71 -0
- package/skill-packs/meta-marketing/council-personas/risk-officer.md +79 -0
- package/skill-packs/meta-marketing/council-personas/strategy-optimizer.md +76 -0
- package/skill-packs/meta-marketing/creative-frameworks.md +176 -0
- package/skill-packs/meta-marketing/mistakes.md +154 -0
- package/skill-packs/meta-marketing/platform-state.md +63 -0
- package/skill-packs/multi-review/REVIEWER_SHARED.md +143 -0
- package/skill-packs/multi-review/SKILL.md +182 -0
- package/skill-packs/system-prompts/SKILL.md +472 -0
|
@@ -0,0 +1,535 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Meta Graph + Marketing API reference (v25.0). Endpoint map, field reference, and raw metaFetch recipes for cases the typed client does not cover. Use as the second-layer fallback before reading live Meta docs.
|
|
3
|
+
api_version: v25.0
|
|
4
|
+
verified_at: 2026-04-25
|
|
5
|
+
official_docs: https://developers.facebook.com/docs/marketing-api/reference/v25.0
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Meta Marketing API — Reference
|
|
9
|
+
|
|
10
|
+
This file is the **second layer** of a three-layer fallback. The typed client (`src/lib/marketing/meta-client.ts`) covers the hot path; this file maps the rest of the surface so the agent knows what is possible without scraping live docs; the live-doc fallback (see SKILL.md §XI) is for anything not covered here.
|
|
11
|
+
|
|
12
|
+
**Promotion rule:** if you use a raw recipe from this file 3+ times, propose adding it to the typed client in the next PR.
|
|
13
|
+
|
|
14
|
+
**Version pin:** all examples target Graph API + Marketing API **v25.0** (released 2026-02-18; current as of 2026-04). Always verify field availability against `https://developers.facebook.com/docs/marketing-api/reference/v25.0` before relying on a field — Meta retires fields aggressively.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## I. Endpoint map (CRUD by entity)
|
|
19
|
+
|
|
20
|
+
Every path is relative to `https://graph.facebook.com/v25.0/` unless marked `[video]` (use `graph-video.facebook.com`). The typed client column shows what's already wrapped — `—` means raw `metaFetch` is required.
|
|
21
|
+
|
|
22
|
+
### AdAccount
|
|
23
|
+
|
|
24
|
+
| Op | Method | Path | Typed |
|
|
25
|
+
|---|---|---|---|
|
|
26
|
+
| List my accounts | GET | `me/adaccounts?fields=...` | `listAdAccounts` |
|
|
27
|
+
| Read account | GET | `<act_id>?fields=...` | `getAdAccount` |
|
|
28
|
+
| Update account | POST | `<act_id>` | — |
|
|
29
|
+
|
|
30
|
+
### Campaign
|
|
31
|
+
|
|
32
|
+
| Op | Method | Path | Typed |
|
|
33
|
+
|---|---|---|---|
|
|
34
|
+
| Create | POST | `<act_id>/campaigns` | `createCampaign` |
|
|
35
|
+
| Read | GET | `<campaign_id>?fields=...` | `getCampaign` |
|
|
36
|
+
| List | GET | `<act_id>/campaigns?fields=...` | — |
|
|
37
|
+
| Update | POST | `<campaign_id>` | `updateCampaign` |
|
|
38
|
+
| Delete | DELETE | `<campaign_id>` | — |
|
|
39
|
+
| Duplicate | POST | `<campaign_id>/copies` | — |
|
|
40
|
+
| Insights | GET | `<campaign_id>/insights?fields=...&level=campaign` | `getInsights` |
|
|
41
|
+
|
|
42
|
+
### AdSet
|
|
43
|
+
|
|
44
|
+
| Op | Method | Path | Typed |
|
|
45
|
+
|---|---|---|---|
|
|
46
|
+
| Create | POST | `<act_id>/adsets` | `createAdSet` |
|
|
47
|
+
| Read | GET | `<adset_id>?fields=...` | — |
|
|
48
|
+
| List | GET | `<act_id>/adsets?fields=...` or `<campaign_id>/adsets` | — |
|
|
49
|
+
| Update | POST | `<adset_id>` | `updateAdSet` |
|
|
50
|
+
| Delete | DELETE | `<adset_id>` | — |
|
|
51
|
+
| Duplicate | POST | `<adset_id>/copies` | — |
|
|
52
|
+
| Insights | GET | `<adset_id>/insights?level=adset` | `getInsights` |
|
|
53
|
+
|
|
54
|
+
### Ad
|
|
55
|
+
|
|
56
|
+
| Op | Method | Path | Typed |
|
|
57
|
+
|---|---|---|---|
|
|
58
|
+
| Create | POST | `<act_id>/ads` | `createAd` |
|
|
59
|
+
| Read | GET | `<ad_id>?fields=...` | — |
|
|
60
|
+
| List | GET | `<act_id>/ads` or `<adset_id>/ads` | — |
|
|
61
|
+
| Update | POST | `<ad_id>` | `updateAd` |
|
|
62
|
+
| Delete | DELETE | `<ad_id>` | — |
|
|
63
|
+
| Duplicate | POST | `<ad_id>/copies` | — |
|
|
64
|
+
| Insights | GET | `<ad_id>/insights?level=ad` | `getInsights` |
|
|
65
|
+
| Preview | GET | `<ad_id>/previews?ad_format=...` | — |
|
|
66
|
+
|
|
67
|
+
### AdCreative
|
|
68
|
+
|
|
69
|
+
| Op | Method | Path | Typed |
|
|
70
|
+
|---|---|---|---|
|
|
71
|
+
| Create | POST | `<act_id>/adcreatives` | `createVideoCreative`, `createImageCreative` |
|
|
72
|
+
| Read | GET | `<creative_id>?fields=...` | — |
|
|
73
|
+
| List | GET | `<act_id>/adcreatives` | — |
|
|
74
|
+
| Update | POST | `<creative_id>` (limited: `name`, `status`) | — |
|
|
75
|
+
| Delete | DELETE | `<creative_id>` | — |
|
|
76
|
+
| Preview | GET | `<creative_id>/previews?ad_format=...` | — |
|
|
77
|
+
|
|
78
|
+
### Asset upload
|
|
79
|
+
|
|
80
|
+
| Op | Method | Path | Typed |
|
|
81
|
+
|---|---|---|---|
|
|
82
|
+
| Image | POST multipart | `<act_id>/adimages` | `uploadImage` |
|
|
83
|
+
| Video (≤50MB) | POST multipart | `<act_id>/advideos` | `uploadVideo` |
|
|
84
|
+
| Video (>50MB) chunked | POST `start\|transfer\|finish` | `<act_id>/advideos` `[video]` | `uploadVideo` (auto-routes) |
|
|
85
|
+
|
|
86
|
+
### Custom audiences
|
|
87
|
+
|
|
88
|
+
| Op | Method | Path | Typed |
|
|
89
|
+
|---|---|---|---|
|
|
90
|
+
| Create | POST | `<act_id>/customaudiences` | — |
|
|
91
|
+
| Read | GET | `<ca_id>?fields=...` | — |
|
|
92
|
+
| List | GET | `<act_id>/customaudiences` | — |
|
|
93
|
+
| Update | POST | `<ca_id>` | — |
|
|
94
|
+
| Delete | DELETE | `<ca_id>` | — |
|
|
95
|
+
| Add users (hashed) | POST | `<ca_id>/users` | — |
|
|
96
|
+
| Remove users | DELETE | `<ca_id>/users` | — |
|
|
97
|
+
|
|
98
|
+
### Insights (async / large windows)
|
|
99
|
+
|
|
100
|
+
| Op | Method | Path | Typed |
|
|
101
|
+
|---|---|---|---|
|
|
102
|
+
| Sync (≤7d in v0) | GET | `<entity_id>/insights?fields=...` | `getInsights` |
|
|
103
|
+
| Async start | POST | `<entity_id>/insights` (returns `report_run_id`) | — (deferred to v1) |
|
|
104
|
+
| Async poll | GET | `<report_run_id>?fields=async_status,async_percent_completion` | — |
|
|
105
|
+
| Async fetch | GET | `<report_run_id>/insights` | — |
|
|
106
|
+
|
|
107
|
+
### Batch
|
|
108
|
+
|
|
109
|
+
| Op | Method | Path | Typed |
|
|
110
|
+
|---|---|---|---|
|
|
111
|
+
| Batch (up to 50 ops) | POST | `/` (root) with `batch=[...]` form field | — |
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## II. Common field reference
|
|
116
|
+
|
|
117
|
+
### Campaign fields
|
|
118
|
+
|
|
119
|
+
| Field | Type | Notes |
|
|
120
|
+
|---|---|---|
|
|
121
|
+
| `id` | string | Read-only |
|
|
122
|
+
| `name` | string | Required on create |
|
|
123
|
+
| `objective` | enum | See §III. Default v0 = `OUTCOME_LEADS` or `OUTCOME_SALES`. **Hard block:** never `OUTCOME_TRAFFIC/ENGAGEMENT/AWARENESS` for revenue campaigns. |
|
|
124
|
+
| `status` | `ACTIVE\|PAUSED\|DELETED\|ARCHIVED` | Always create as `PAUSED`. |
|
|
125
|
+
| `effective_status` | enum (read-only) | What Meta is actually doing with it (vs requested status). |
|
|
126
|
+
| `special_ad_categories` | string[] | Required (empty array OK). Values: `EMPLOYMENT`, `HOUSING`, `CREDIT`, `ISSUES_ELECTIONS_POLITICS`, `ONLINE_GAMBLING_AND_GAMING`, `FINANCIAL_PRODUCTS_SERVICES`. |
|
|
127
|
+
| `daily_budget` | string (minor unit) | Campaign Budget Optimization. Mutually exclusive with adset-level budgets. |
|
|
128
|
+
| `lifetime_budget` | string (minor unit) | Mutually exclusive with `daily_budget`. |
|
|
129
|
+
| `bid_strategy` | enum | `LOWEST_COST_WITHOUT_CAP`, `LOWEST_COST_WITH_BID_CAP`, `COST_CAP`. |
|
|
130
|
+
| `buying_type` | `AUCTION\|RESERVED` | `AUCTION` is the v0 default. |
|
|
131
|
+
| `pacing_type` | string[] | `["standard"]` (default), `["no_pacing"]`. |
|
|
132
|
+
| `spend_cap` | string (minor unit) | Hard cap on lifetime spend. |
|
|
133
|
+
| `start_time` / `stop_time` | ISO 8601 | `YYYY-MM-DDTHH:MM:SS+0000`. |
|
|
134
|
+
| `adlabels` | object[] | `[{ name: "<label>" }]` for grouping. |
|
|
135
|
+
| `source_campaign_id` | string | Set on duplicate via `/copies`. |
|
|
136
|
+
| `is_skadnetwork_attribution` | bool | iOS 14+ tracking. |
|
|
137
|
+
|
|
138
|
+
### AdSet fields
|
|
139
|
+
|
|
140
|
+
| Field | Type | Notes |
|
|
141
|
+
|---|---|---|
|
|
142
|
+
| `name`, `campaign_id` | string | Required. |
|
|
143
|
+
| `daily_budget` / `lifetime_budget` | string (minor unit) | Exactly one if campaign isn't using CBO. |
|
|
144
|
+
| `optimization_goal` | enum | See §III. v0 default for Sales = `OFFSITE_CONVERSIONS`. |
|
|
145
|
+
| `billing_event` | `IMPRESSIONS\|LINK_CLICKS\|THRUPLAY` | `IMPRESSIONS` is the safe default. |
|
|
146
|
+
| `bid_strategy` | enum | Inherits from campaign if unset. |
|
|
147
|
+
| `bid_amount` | int (minor unit) | Required when `bid_strategy=LOWEST_COST_WITH_BID_CAP` or `COST_CAP`. |
|
|
148
|
+
| `bid_constraints` | object | `{ "<event>": { "min": <int>, "max": <int> } }`. Advanced. |
|
|
149
|
+
| `promoted_object` | object | `{ pixel_id, custom_event_type, page_id?, application_id? }` — required for `OFFSITE_CONVERSIONS`. |
|
|
150
|
+
| `targeting` | object | See §IV. |
|
|
151
|
+
| `attribution_spec` | object[] | `[{ event_type: "CLICK_THROUGH", window_days: 7 }]`. v0 default in Meta is 1-day-view (changed 2026); override here for longer cycles. |
|
|
152
|
+
| `dsa_beneficiary` | string | **Mandatory in EU since 2025.** Legal entity benefiting from the ads. |
|
|
153
|
+
| `dsa_payor` | string | **Mandatory in EU since 2025.** Legal entity paying. |
|
|
154
|
+
| `frequency_control_specs` | object[] | `[{ event: "IMPRESSIONS", interval_days: 7, max_frequency: 3 }]`. |
|
|
155
|
+
| `pacing_type` | string[] | Default `["standard"]`. |
|
|
156
|
+
| `start_time` / `end_time` | ISO 8601 | Adset-level scheduling. |
|
|
157
|
+
| `tune_for_category` | string | Special category targeting. |
|
|
158
|
+
| `targeting_optimization` | string | `"none"` to disable Advantage+ Audience Expansion. |
|
|
159
|
+
| `multi_optimization_goal_weight` | enum | Multi-objective optimization. Advanced. |
|
|
160
|
+
|
|
161
|
+
### Ad fields
|
|
162
|
+
|
|
163
|
+
| Field | Type | Notes |
|
|
164
|
+
|---|---|---|
|
|
165
|
+
| `name`, `adset_id` | string | Required. |
|
|
166
|
+
| `creative` | object | `{ creative_id }` is the simple form. Inline creative also supported. |
|
|
167
|
+
| `status` | enum | Always `PAUSED` on create. |
|
|
168
|
+
| `tracking_specs` | object[] | View-level tracking events. |
|
|
169
|
+
| `conversion_specs` | object[] | What counts as a conversion for *this* ad (override adset). |
|
|
170
|
+
| `view_tags` | string[] | 3rd-party impression pixels. |
|
|
171
|
+
| `adlabels` | object[] | `[{ name: "<label>" }]`. |
|
|
172
|
+
| `source_ad_id` | string | Set on duplicate via `/copies`. |
|
|
173
|
+
|
|
174
|
+
### AdCreative fields
|
|
175
|
+
|
|
176
|
+
| Field | Type | Notes |
|
|
177
|
+
|---|---|---|
|
|
178
|
+
| `name` | string | Internal label. |
|
|
179
|
+
| `object_story_spec` | object | `{ page_id, instagram_actor_id?, link_data? \| photo_data? \| video_data? }`. |
|
|
180
|
+
| `asset_feed_spec` | object | Multi-asset / dynamic creative. See §V. |
|
|
181
|
+
| `dynamic_creative_specs` | object | Dynamic Creative Optimization. |
|
|
182
|
+
| `template_data` | object | Carousel / collection ads. |
|
|
183
|
+
| `image_hash` | string | Single-image shortcut. |
|
|
184
|
+
| `image_url` | string | External image (will be cached). |
|
|
185
|
+
| `video_id` | string | Single-video shortcut. |
|
|
186
|
+
| `link_url`, `link_destination_display_url` | string | Landing + display URL. |
|
|
187
|
+
| `body`, `title`, `description` | string | Creative copy when not using `asset_feed_spec`. |
|
|
188
|
+
| `call_to_action` | object | `{ type: <CTA>, value: { link, link_format } }`. |
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## III. Enum reference
|
|
193
|
+
|
|
194
|
+
### `objective` (campaign)
|
|
195
|
+
|
|
196
|
+
| Value | Use for |
|
|
197
|
+
|---|---|
|
|
198
|
+
| `OUTCOME_SALES` | Purchases, e-com checkouts. |
|
|
199
|
+
| `OUTCOME_LEADS` | Lead gen forms, sign-ups. |
|
|
200
|
+
| `OUTCOME_TRAFFIC` | **Banned for revenue campaigns** per `mistakes.md #1`. |
|
|
201
|
+
| `OUTCOME_ENGAGEMENT` | Likes, comments, video views — non-revenue. |
|
|
202
|
+
| `OUTCOME_AWARENESS` | Reach, brand lift — top-of-funnel only. |
|
|
203
|
+
| `OUTCOME_APP_PROMOTION` | App installs / app events. |
|
|
204
|
+
|
|
205
|
+
### `optimization_goal` (adset)
|
|
206
|
+
|
|
207
|
+
| Value | Use with |
|
|
208
|
+
|---|---|
|
|
209
|
+
| `OFFSITE_CONVERSIONS` | Sales / leads with Pixel + CAPI. **v0 default.** |
|
|
210
|
+
| `LINK_CLICKS` | When `OUTCOME_TRAFFIC` (rare in v0). |
|
|
211
|
+
| `LANDING_PAGE_VIEWS` | LP-quality traffic. |
|
|
212
|
+
| `LEAD_GENERATION` | Native lead forms (no website). |
|
|
213
|
+
| `IMPRESSIONS` | Awareness only. |
|
|
214
|
+
| `REACH` | Unique people, not impressions. |
|
|
215
|
+
| `THRUPLAY` | Video views ≥15s or full play. |
|
|
216
|
+
| `VALUE` | Bid for highest predicted purchase value. Advanced. |
|
|
217
|
+
|
|
218
|
+
### `call_to_action_types`
|
|
219
|
+
|
|
220
|
+
`SIGN_UP`, `LEARN_MORE`, `GET_OFFER`, `SUBSCRIBE`, `INSTALL_APP`, `DOWNLOAD`, `BOOK_TRAVEL`, `SHOP_NOW`, `SEND_MESSAGE`, `WHATSAPP_MESSAGE`, `APPLY_NOW`, `CONTACT_US`, `GET_DIRECTIONS`, `GET_QUOTE`, `WATCH_MORE`, `LISTEN_NOW`.
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## IV. Targeting spec (full surface)
|
|
225
|
+
|
|
226
|
+
The typed `Targeting` interface in `meta-client.ts` is a slim subset. Below is the full common-case spec. Pass as a stringified JSON object in the `targeting` form param.
|
|
227
|
+
|
|
228
|
+
```json
|
|
229
|
+
{
|
|
230
|
+
"geo_locations": {
|
|
231
|
+
"countries": ["TR"],
|
|
232
|
+
"regions": [{ "key": "<region_id>" }],
|
|
233
|
+
"cities": [{ "key": "<city_id>", "radius": 10, "distance_unit": "kilometer" }],
|
|
234
|
+
"zips": [{ "key": "TR:34000" }],
|
|
235
|
+
"location_types": ["home", "recent"]
|
|
236
|
+
},
|
|
237
|
+
"age_min": 18,
|
|
238
|
+
"age_max": 65,
|
|
239
|
+
"genders": [1, 2],
|
|
240
|
+
"locales": [6, 24],
|
|
241
|
+
|
|
242
|
+
"custom_audiences": [{ "id": "<ca_id>" }],
|
|
243
|
+
"excluded_custom_audiences": [{ "id": "<ca_id>" }],
|
|
244
|
+
|
|
245
|
+
"flexible_spec": [
|
|
246
|
+
{
|
|
247
|
+
"interests": [{ "id": "<int_id>", "name": "Education" }],
|
|
248
|
+
"behaviors": [{ "id": "<beh_id>", "name": "Small business owners" }],
|
|
249
|
+
"demographics": [{ "id": "<dem_id>", "name": "Parents (all)" }]
|
|
250
|
+
}
|
|
251
|
+
],
|
|
252
|
+
"exclusions": {
|
|
253
|
+
"interests": [{ "id": "<int_id>" }]
|
|
254
|
+
},
|
|
255
|
+
|
|
256
|
+
"publisher_platforms": ["facebook", "instagram", "audience_network", "messenger"],
|
|
257
|
+
"facebook_positions": ["feed", "right_hand_column", "marketplace", "video_feeds", "story", "search", "instream_video", "facebook_reels"],
|
|
258
|
+
"instagram_positions": ["stream", "story", "explore", "reels", "shop", "explore_home"],
|
|
259
|
+
"audience_network_positions": ["classic", "rewarded_video"],
|
|
260
|
+
"messenger_positions": ["messenger_home", "story"],
|
|
261
|
+
"device_platforms": ["mobile", "desktop"],
|
|
262
|
+
"user_os": ["iOS", "Android"],
|
|
263
|
+
|
|
264
|
+
"targeting_automation": { "advantage_audience": 1 },
|
|
265
|
+
"brand_safety_content_filter_levels": ["FACEBOOK_STANDARD", "AN_STANDARD"],
|
|
266
|
+
|
|
267
|
+
"education_majors": [{ "id": "<id>" }],
|
|
268
|
+
"education_schools": [{ "id": "<id>" }],
|
|
269
|
+
"education_statuses": [1, 2, 3],
|
|
270
|
+
"industries": [{ "id": "<id>" }],
|
|
271
|
+
"interested_in": [1, 2],
|
|
272
|
+
"life_events": [{ "id": "<id>" }],
|
|
273
|
+
"relationship_statuses": [1, 2, 3],
|
|
274
|
+
"work_employers": [{ "id": "<id>" }],
|
|
275
|
+
"work_positions": [{ "id": "<id>" }]
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
**Default per `account-ops.md §II`:** broad targeting, no detailed targeting, no age/gender restriction unless legal — Meta's delivery treats targeting as suggestions. Use `targeting_automation.advantage_audience: 1` and let Meta find the buyers.
|
|
280
|
+
|
|
281
|
+
**Targeting Search API** for resolving names → IDs: `GET /search?type=adinterest&q=<query>` (also `adgeolocation`, `adworkemployer`, `adeducationschool`, etc.).
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
## V. `asset_feed_spec` (full surface)
|
|
286
|
+
|
|
287
|
+
```json
|
|
288
|
+
{
|
|
289
|
+
"videos": [{ "video_id": "<id>", "thumbnail_hash": "<hash>" }],
|
|
290
|
+
"images": [{ "hash": "<hash>" }],
|
|
291
|
+
|
|
292
|
+
"bodies": [{ "text": "<copy>" }],
|
|
293
|
+
"titles": [{ "text": "<headline>" }],
|
|
294
|
+
"descriptions": [{ "text": "<description>" }],
|
|
295
|
+
"captions": [{ "text": "<caption>" }],
|
|
296
|
+
"link_descriptions": [{ "text": "<link description>" }],
|
|
297
|
+
|
|
298
|
+
"link_urls": [{ "website_url": "https://...", "display_url": "example.com" }],
|
|
299
|
+
"call_to_action_types": ["SIGN_UP"],
|
|
300
|
+
|
|
301
|
+
"ad_formats": ["SINGLE_VIDEO", "SINGLE_IMAGE", "CAROUSEL"],
|
|
302
|
+
|
|
303
|
+
"optimization_type": "PLACEMENT",
|
|
304
|
+
"autotranslate": ["es_ES", "tr_TR"],
|
|
305
|
+
|
|
306
|
+
"additional_data": {
|
|
307
|
+
"multi_share_end_card": false,
|
|
308
|
+
"is_click_to_message": false
|
|
309
|
+
},
|
|
310
|
+
|
|
311
|
+
"asset_customization_rules": [
|
|
312
|
+
{
|
|
313
|
+
"customization_spec": {
|
|
314
|
+
"publisher_platforms": ["instagram"],
|
|
315
|
+
"instagram_positions": ["story", "reels"]
|
|
316
|
+
},
|
|
317
|
+
"video_label": "<label>",
|
|
318
|
+
"image_label": "<label>",
|
|
319
|
+
"body_label": { "name": "<label>" }
|
|
320
|
+
}
|
|
321
|
+
]
|
|
322
|
+
}
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
**Hook-swap pattern (per `copy-formulas.md §3`):** keep the same `videos[].video_id` body (seconds 4–end) across multiple ads, vary the `bodies` and `titles` to test different hook framings. Aim for 5–10 hook variants per body.
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
## VI. Raw `metaFetch` recipes
|
|
330
|
+
|
|
331
|
+
Use these when the typed client doesn't have the verb. All assume the operator is already in a CLI command and has built `ctx` via `liveCtxFromEnv(loadEnv())`.
|
|
332
|
+
|
|
333
|
+
### 1. Delete a campaign / adset / ad / creative
|
|
334
|
+
|
|
335
|
+
```ts
|
|
336
|
+
import { metaFetch } from '../lib/marketing/meta-fetch.js';
|
|
337
|
+
await metaFetch(ctx, {
|
|
338
|
+
method: 'DELETE',
|
|
339
|
+
path: '<entity_id>',
|
|
340
|
+
});
|
|
341
|
+
// Returns { success: true }. Idempotent — calling on already-deleted is a no-op.
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### 2. List campaigns with cursor pagination
|
|
345
|
+
|
|
346
|
+
```ts
|
|
347
|
+
const fields = 'id,name,objective,status,effective_status,daily_budget,created_time,updated_time';
|
|
348
|
+
let next: string | null = null;
|
|
349
|
+
const all: Record<string, unknown>[] = [];
|
|
350
|
+
do {
|
|
351
|
+
const resp = await metaFetch(ctx, {
|
|
352
|
+
method: 'GET',
|
|
353
|
+
path: `${ctx.adAccountId}/campaigns`,
|
|
354
|
+
query: { fields, limit: 100, ...(next ? { after: next } : {}) },
|
|
355
|
+
}) as { data: Record<string, unknown>[]; paging?: { cursors?: { after: string }; next?: string } };
|
|
356
|
+
all.push(...resp.data);
|
|
357
|
+
next = resp.paging?.next ? resp.paging.cursors?.after ?? null : null;
|
|
358
|
+
} while (next);
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
Pattern works for `/adsets`, `/ads`, `/adcreatives`, `/customaudiences` — swap the path leaf.
|
|
362
|
+
|
|
363
|
+
### 3. Duplicate a campaign / adset / ad
|
|
364
|
+
|
|
365
|
+
```ts
|
|
366
|
+
await metaFetch(ctx, {
|
|
367
|
+
method: 'POST',
|
|
368
|
+
path: `<source_id>/copies`,
|
|
369
|
+
params: {
|
|
370
|
+
deep_copy: true, // also copy children (campaign → adsets → ads)
|
|
371
|
+
status_option: 'PAUSED', // duplicates always created paused
|
|
372
|
+
rename_options: { rename_strategy: 'DEEP_RENAME', rename_suffix: ' (copy)' },
|
|
373
|
+
start_time: '2026-05-01T00:00:00+0000', // optional reschedule
|
|
374
|
+
},
|
|
375
|
+
});
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
`deep_copy: false` gives a shallow copy (children point to originals — useful when duplicating an adset to edit a single field per `account-ops.md §II`'s "duplicate before editing" rule).
|
|
379
|
+
|
|
380
|
+
### 4. Batch — flip many entities atomically (close to it)
|
|
381
|
+
|
|
382
|
+
```ts
|
|
383
|
+
const batch = entities.map((e) => ({
|
|
384
|
+
method: 'POST',
|
|
385
|
+
relative_url: `${e.id}?status=PAUSED`,
|
|
386
|
+
}));
|
|
387
|
+
await metaFetch(ctx, {
|
|
388
|
+
method: 'POST',
|
|
389
|
+
path: '', // root
|
|
390
|
+
params: { batch: JSON.stringify(batch) },
|
|
391
|
+
});
|
|
392
|
+
// Each item in the response array maps to the corresponding batch entry.
|
|
393
|
+
// Each can succeed/fail independently — Meta does NOT roll back the whole batch.
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
Batch limit: 50 ops per call. For `mk launch <cohort>` flipping a campaign + 1 adset + 5 ads to ACTIVE, one batch call replaces 7 round trips.
|
|
397
|
+
|
|
398
|
+
### 5. Create a custom audience (website visitors retargeting)
|
|
399
|
+
|
|
400
|
+
```ts
|
|
401
|
+
await metaFetch(ctx, {
|
|
402
|
+
method: 'POST',
|
|
403
|
+
path: `${ctx.adAccountId}/customaudiences`,
|
|
404
|
+
params: {
|
|
405
|
+
name: 'Site visitors 30d',
|
|
406
|
+
subtype: 'WEBSITE',
|
|
407
|
+
rule: JSON.stringify({
|
|
408
|
+
inclusions: {
|
|
409
|
+
operator: 'or',
|
|
410
|
+
rules: [{ event_sources: [{ id: ctx.pixelId, type: 'pixel' }], retention_seconds: 30 * 86400, filter: { operator: 'and', filters: [{ field: 'url', operator: 'i_contains', value: 'example.com' }] } }],
|
|
411
|
+
},
|
|
412
|
+
}),
|
|
413
|
+
retention_days: 30,
|
|
414
|
+
description: 'Visitors in last 30 days',
|
|
415
|
+
},
|
|
416
|
+
});
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
### 6. Read insights with breakdowns (e.g. by placement)
|
|
420
|
+
|
|
421
|
+
```ts
|
|
422
|
+
await metaFetch(ctx, {
|
|
423
|
+
method: 'GET',
|
|
424
|
+
path: `<campaign_id>/insights`,
|
|
425
|
+
query: {
|
|
426
|
+
fields: 'spend,impressions,clicks,ctr,cpm,purchase_roas,actions',
|
|
427
|
+
level: 'ad',
|
|
428
|
+
breakdowns: 'publisher_platform,platform_position,impression_device',
|
|
429
|
+
date_preset: 'last_7d',
|
|
430
|
+
},
|
|
431
|
+
});
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
Allowed breakdowns: `age`, `gender`, `country`, `region`, `dma`, `publisher_platform`, `platform_position`, `device_platform`, `impression_device`, `product_id`, `frequency_value`. Some are mutually exclusive.
|
|
435
|
+
|
|
436
|
+
### 7. Async insights for windows >7d (v1 — defer in v0)
|
|
437
|
+
|
|
438
|
+
```ts
|
|
439
|
+
// Step 1 — start
|
|
440
|
+
const start = await metaFetch(ctx, {
|
|
441
|
+
method: 'POST',
|
|
442
|
+
path: `<entity_id>/insights`,
|
|
443
|
+
params: { date_preset: 'last_30d', level: 'ad', fields: '...' },
|
|
444
|
+
}) as { report_run_id: string };
|
|
445
|
+
|
|
446
|
+
// Step 2 — poll
|
|
447
|
+
let status = 'Job Not Started';
|
|
448
|
+
while (!['Job Completed', 'Job Failed', 'Job Skipped'].includes(status)) {
|
|
449
|
+
await new Promise((r) => setTimeout(r, 5000));
|
|
450
|
+
const poll = await metaFetch(ctx, {
|
|
451
|
+
method: 'GET',
|
|
452
|
+
path: start.report_run_id,
|
|
453
|
+
query: { fields: 'async_status,async_percent_completion' },
|
|
454
|
+
}) as { async_status: string };
|
|
455
|
+
status = poll.async_status;
|
|
456
|
+
}
|
|
457
|
+
if (status !== 'Job Completed') throw new Error(`async insights ${status}`);
|
|
458
|
+
|
|
459
|
+
// Step 3 — fetch
|
|
460
|
+
const data = await metaFetch(ctx, {
|
|
461
|
+
method: 'GET',
|
|
462
|
+
path: `${start.report_run_id}/insights`,
|
|
463
|
+
query: { limit: 5000 },
|
|
464
|
+
});
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
### 8. Resolve a targeting interest by name → id
|
|
468
|
+
|
|
469
|
+
```ts
|
|
470
|
+
await metaFetch(ctx, {
|
|
471
|
+
method: 'GET',
|
|
472
|
+
path: 'search',
|
|
473
|
+
query: { type: 'adinterest', q: 'Education', limit: 25 },
|
|
474
|
+
});
|
|
475
|
+
// Returns { data: [{ id, name, audience_size_lower_bound, audience_size_upper_bound, path, topic }] }
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
### 9. Get an ad preview (rendered HTML)
|
|
479
|
+
|
|
480
|
+
```ts
|
|
481
|
+
await metaFetch(ctx, {
|
|
482
|
+
method: 'GET',
|
|
483
|
+
path: `<ad_id>/previews`,
|
|
484
|
+
query: { ad_format: 'MOBILE_FEED_STANDARD' },
|
|
485
|
+
});
|
|
486
|
+
// Returns { data: [{ body: "<html>..." }] }
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
Ad formats: `MOBILE_FEED_STANDARD`, `DESKTOP_FEED_STANDARD`, `INSTAGRAM_STANDARD`, `INSTAGRAM_STORY`, `INSTAGRAM_REELS`, `RIGHT_COLUMN_STANDARD`, `MESSENGER_MOBILE_INBOX_MEDIA`, `FACEBOOK_REELS_MOBILE`, `MARKETPLACE_MOBILE`.
|
|
490
|
+
|
|
491
|
+
### 10. Read an entity with all common fields
|
|
492
|
+
|
|
493
|
+
```ts
|
|
494
|
+
// Campaign
|
|
495
|
+
await metaFetch(ctx, {
|
|
496
|
+
method: 'GET',
|
|
497
|
+
path: '<campaign_id>',
|
|
498
|
+
query: { fields: 'id,name,objective,status,effective_status,configured_status,daily_budget,lifetime_budget,bid_strategy,buying_type,start_time,stop_time,spend_cap,special_ad_categories,pacing_type,created_time,updated_time' },
|
|
499
|
+
});
|
|
500
|
+
// AdSet — replace fields with: id,name,campaign_id,status,effective_status,daily_budget,lifetime_budget,bid_amount,bid_strategy,billing_event,optimization_goal,promoted_object,targeting,attribution_spec,start_time,end_time,frequency_control_specs,pacing_type,dsa_beneficiary,dsa_payor
|
|
501
|
+
// Ad — fields: id,name,adset_id,creative,status,effective_status,tracking_specs,conversion_specs,created_time,updated_time
|
|
502
|
+
// Creative — fields: id,name,object_story_spec,asset_feed_spec,image_hash,video_id,call_to_action,body,title
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
---
|
|
506
|
+
|
|
507
|
+
## VII. Error codes (cross-reference)
|
|
508
|
+
|
|
509
|
+
The `metaFetch` retry whitelist is `{1, 2, 4, 17, 32, 613}`. Common non-retried codes you'll see:
|
|
510
|
+
|
|
511
|
+
| Code | Meaning | Action |
|
|
512
|
+
|---|---|---|
|
|
513
|
+
| 100 | Invalid parameter | Read the message — usually a malformed field. Do not retry; fix and resubmit. |
|
|
514
|
+
| 190 | OAuth token expired | `TokenExpiredError`. Regenerate System User Token and update `.env`. |
|
|
515
|
+
| 200 | Permission denied | Token lacks scope or app role. |
|
|
516
|
+
| 270 | App must be approved | App Review required for the called endpoint. |
|
|
517
|
+
| 368 | Action attempted has been deemed abusive | Rare. Usually bulk creates flagged as spam. |
|
|
518
|
+
| 1487 | Edits on this object are limited | Snow-globe violation — Meta's own rate limit on rapid edits. Wait. |
|
|
519
|
+
| 80004 | Spending limit reached | Account spend cap hit. |
|
|
520
|
+
| 80008 | Application request limit reached | Different from user-level — affects the entire app. |
|
|
521
|
+
|
|
522
|
+
For the full list: `https://developers.facebook.com/docs/graph-api/guides/error-handling/`.
|
|
523
|
+
|
|
524
|
+
---
|
|
525
|
+
|
|
526
|
+
## VIII. When this file isn't enough — live-doc fallback
|
|
527
|
+
|
|
528
|
+
If the operator asks for something not covered here:
|
|
529
|
+
|
|
530
|
+
1. Fetch `https://developers.facebook.com/docs/marketing-api/reference/v25.0/<entity>` (or the relevant endpoint page).
|
|
531
|
+
2. Construct a raw `metaFetch(ctx, { method, path, params })` call following the patterns in §VI.
|
|
532
|
+
3. Run dry-run first (`ctx.dryRun = true`), show the operator the request shape.
|
|
533
|
+
4. After operator confirms, run live.
|
|
534
|
+
5. **Add the recipe back into §VI of this file** so next time it's a layer-2 hit, not a layer-3 doc fetch.
|
|
535
|
+
6. If the same recipe is used 3+ times, propose adding a typed wrapper to `meta-client.ts` in the next PR.
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Ad Copy Formulas"
|
|
3
|
+
lane: "cross-lane (paid-ad-creative + paid-ad-account-ops)"
|
|
4
|
+
status: "draft — corpus-derived, not yet skill-pack ready"
|
|
5
|
+
speakers: 2 (Jared Robinson/Creative Don, Ben Heath)
|
|
6
|
+
videos: 2 (ooF7rNBYAog, dAJyqo6wnq4)
|
|
7
|
+
updated: "2026-04-25"
|
|
8
|
+
note: "Cross-lane — apply to both creative briefs and account-ops copy decisions. Strongest single cross-source signal in corpus."
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Ad Copy Formulas
|
|
12
|
+
|
|
13
|
+
Two formulas from the corpus, both with cross-lane corroboration. These are about *what goes in the ad* — structure, hooks, and variation — not account settings.
|
|
14
|
+
|
|
15
|
+
**Source key:**
|
|
16
|
+
- Jared = `_youtube__ooF7rNBYAog` (Jared Robinson / Creative Don, 1 voice, paid-ad-creative lane)
|
|
17
|
+
- Ben = `_youtube__dAJyqo6wnq4` + `kuSq-pmNfnM` (Ben Heath, 1 voice, paid-ad-account-ops lane)
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 1. The Five-Part Copy Structure
|
|
22
|
+
|
|
23
|
+
**Callout → Agitation → Benefit → Scarcity → CTA**
|
|
24
|
+
|
|
25
|
+
This is the strongest single cross-source signal in the corpus: two speakers from two different lanes, neither aware of the other, describe the same ad copy architecture.
|
|
26
|
+
|
|
27
|
+
### The structure
|
|
28
|
+
|
|
29
|
+
| Part | Purpose | Length | Example shape |
|
|
30
|
+
|---|---|---|---|
|
|
31
|
+
| **Callout** | Identify the target person. Make them feel "that's me." | 1 line | *"[Role] who [specific situation], read this."* |
|
|
32
|
+
| **Agitation** | Name the pain they already feel. Don't introduce a new problem — confirm the one they're living. | 1–3 lines | Specific moment + channel + frequency the pain shows up. |
|
|
33
|
+
| **Benefit** | What changes with your product. Concrete and specific — not "save time", but a measurable outcome ("4 minutes", "0 follow-ups", "Sunday back"). | 1–2 lines | *"[Product] handles all of that automatically."* |
|
|
34
|
+
| **Scarcity** | A real reason to act now. Deadline, limited availability, price window, or first-mover framing. **Avoid fake scarcity** (no "limited seats" on a SaaS product). | 1 line | Time-bound offer / first-mover framing / social proof + FOMO. |
|
|
35
|
+
| **CTA** | Single, clear, imperative action. No options. | 1 line | *"Start free today."* / *"Book a demo."* — one verb, one path. |
|
|
36
|
+
|
|
37
|
+
### Why it works
|
|
38
|
+
|
|
39
|
+
- **Callout** stops the scroll for the right person and lets the wrong person self-select out (reduces wasted impressions).
|
|
40
|
+
- **Agitation** creates emotional resonance before the pitch. People need to feel understood before they'll trust a solution.
|
|
41
|
+
- **Benefit** translates the product into the outcome the person wants — not a feature list.
|
|
42
|
+
- **Scarcity** moves "I should try this" from a future intention to a present decision.
|
|
43
|
+
- **CTA** removes decision paralysis. One action, no alternatives.
|
|
44
|
+
|
|
45
|
+
### Sources
|
|
46
|
+
|
|
47
|
+
- Jared Robinson / Creative Don (`_youtube__ooF7rNBYAog` §2–§4): explicit 5-part breakdown with examples; described as the framework behind his clients' winning ads.
|
|
48
|
+
- Ben Heath (`_youtube__dAJyqo6wnq4` §5): independently describes the same sequence in the context of ad creative reviews; does not give it a named framework but the architecture is identical.
|
|
49
|
+
|
|
50
|
+
**Cross-lane status:** Jared = paid-ad-creative practitioner. Ben = paid-ad-account-ops practitioner. Neither references the other. Independent convergence on the same structure is strong evidence it reflects genuine copy performance patterns, not a single school of thought.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
### Application notes (callout / agitation / benefit / scarcity craftsmanship)
|
|
55
|
+
|
|
56
|
+
**Callout — three shapes that work (pick one per creative, not all):**
|
|
57
|
+
- Direct ICP address: `[Role/situation], read this.`
|
|
58
|
+
- Lead with agitation: `Same conversation every month: [specific pain]. Hours of it.` — skip the explicit callout when the agitation already tags the ICP.
|
|
59
|
+
- Social-proof callout: `[N] [role]s already stopped doing this.`
|
|
60
|
+
|
|
61
|
+
**Agitation specificity rule:** The more specific the agitation, the more it lands. *"It takes time"* is weak. *"Sunday evenings messaging customers on WhatsApp"* is strong — it names a specific moment, channel, and frequency. Specificity proves you actually know the ICP.
|
|
62
|
+
|
|
63
|
+
**Benefit — avoid feature-first phrasing:**
|
|
64
|
+
|
|
65
|
+
| Weak (feature) | Strong (outcome) |
|
|
66
|
+
|---|---|
|
|
67
|
+
| `Automated payment reminders` | `Stop chasing customers entirely` |
|
|
68
|
+
| `Student progress tracking` | `See which student is falling behind in 10 seconds` |
|
|
69
|
+
| `Digital attendance` | `Know who didn't show up in 30 seconds` |
|
|
70
|
+
|
|
71
|
+
The pattern: features describe what the product *has*; outcomes describe what the user *no longer has to do*. Lead with the absence, not the presence.
|
|
72
|
+
|
|
73
|
+
**Scarcity — real vs fake:**
|
|
74
|
+
Fake scarcity ("limited seats" on an unlimited SaaS product) degrades trust. Use:
|
|
75
|
+
- Time-bound offers tied to actual promotions (`Through end of month`).
|
|
76
|
+
- First-mover / lock-in framing (`Beta pricing locked for early adopters`).
|
|
77
|
+
- Social proof + FOMO (`37 more joined this month`) — only if the number is real and verifiable.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## 2. AI-Assisted Copy Generation — Human-in-the-Loop
|
|
82
|
+
|
|
83
|
+
**Rule:** Use AI to generate multiple copy options across the 5-part structure; human operator filters and selects. AI is the volume engine; human judgment is the quality gate.
|
|
84
|
+
|
|
85
|
+
**Workflow:**
|
|
86
|
+
1. Brief the AI with: target persona, product differentiator, one specific pain to agitate, offer/scarcity detail.
|
|
87
|
+
2. Generate 5–10 variants of the callout and agitation (the parts that most affect stop-rate).
|
|
88
|
+
3. Human reads all variants and picks 2–3 that "sound true" — feel native, not generic.
|
|
89
|
+
4. Assemble selected callout + agitation with hand-written benefit + scarcity + CTA.
|
|
90
|
+
|
|
91
|
+
**Why human filters:** AI tends to default to competent but generic phrasing. The callout and agitation sections require cultural specificity and emotional accuracy that AI cannot reliably self-assess. A human reader immediately knows when agitation feels real vs. when it's a paraphrase of the problem statement.
|
|
92
|
+
|
|
93
|
+
**Sources:** Jared (`ooF7rNBYAog` §5), Ben (`dAJyqo6wnq4` §7) — both independently describe this human-filters-AI-options workflow.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## 3. Hook-Swap Variation Strategy
|
|
98
|
+
|
|
99
|
+
**Rule:** To scale creative volume without proportional production cost, keep the same video body (seconds 4 to end) and produce 5–10 different 3-second hook openings. Each hook variant is a separate ad. This yields 10 distinct ads from a single shoot.
|
|
100
|
+
|
|
101
|
+
**Why 3 seconds:** 90%+ of viewers do not reach second 4. The hook is the only differentiating variable for the majority of ad exposures. A hook swap is sufficient to bypass the "I've seen this before" filter — the viewer never reaches the repeated content.
|
|
102
|
+
|
|
103
|
+
**Production workflow (with influencers or UGC actors):**
|
|
104
|
+
```
|
|
105
|
+
"Record the opening line again with these 5 different first sentences."
|
|
106
|
+
"Record one in this location, one turned around to show the other background."
|
|
107
|
+
```
|
|
108
|
+
Location change + line change = 10 combinations from 2 short reshoot sessions.
|
|
109
|
+
|
|
110
|
+
**Ad fatigue use case:** When a winning ad starts to tire (rising frequency, falling ROAS), introduce hook variants before replacing the whole creative. The body has already proven it converts — swap the hook before replacing what works.
|
|
111
|
+
|
|
112
|
+
**Application:** For any video ad that performs, produce hook variants before assuming the ad has run its course. The angle × format × hook grid in `creative-frameworks.md` can be extended with hook-swap variants within each cell (same angle + format, multiple hook types).
|
|
113
|
+
|
|
114
|
+
**Source:** Ben Heath (`_youtube__kuSq-pmNfnM` §1) — single speaker; not yet corroborated. Treat as a high-confidence production heuristic pending second source.
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## What this file does NOT cover
|
|
119
|
+
|
|
120
|
+
- Account structure, targeting, campaign topology → `account-ops.md`
|
|
121
|
+
- Creative grid framework (angle × format × hook), reciprocity offer framing → `creative-frameworks.md`
|
|
122
|
+
- Project-specific cohort copy, named ads, language-specific hooks → maintained by the calling project, not by this skill
|
|
123
|
+
- Failure modes / common mistakes → `mistakes.md`
|