The atom: setup_process
There is one setup_process per event, stored under
/setup_processes/{eid}. It holds:
- Goal (
UTILIZATION,ROAS,VISIBILITY,LINK_CLICKS). - Total budget, start date, end date.
- Selected taste clusters at a fixed
tc_run_id. - Creatives per cluster (headline, body, media, CTA).
- Targeting per cluster (geo, demographics, custom audiences).
- Integration details (ad account, pixel, lead form, …).
- DSA payor / beneficiary (EU compliance).
Reading published campaigns
After publish, list campaigns under an event:(eid, tc, tc_run_id).
Post-campaign performance
Campaign performance is read via the Meta integration endpoint:X-Preferred-Partner-Id header. The
attribution model selection (FD, META, EXTERNAL) is applied via
GET /PUT /events/{eid}/attribution_model.
See Wave — Attribution.
Common gotchas
`/campaigns_setup` ≠ `/setup_processes/{eid}`
`/campaigns_setup` ≠ `/setup_processes/{eid}`
The “edit one published cluster” endpoint is
POST /campaigns_setup
(plural, no {eid} in URL, eid goes in the body). It is not
the same as PUT /setup_processes/{eid}. They are two different
lifecycle stages.One setup_process per event
One setup_process per event
There is no
setupId in the URL. Concurrent edits across tabs race
on the same row. The reference webapp uses a module-level
AbortController to drop stale PUTs.Autosave PUTs send the full payload, not diffs
Autosave PUTs send the full payload, not diffs
The endpoint expects the full setup_process. Sending a partial
resets unspecified fields to defaults.
Goal values are enum-style, not natural language
Goal values are enum-style, not natural language
UTILIZATION, ROAS, VISIBILITY, LINK_CLICKS — not tickets,
revenue, reach.