Attribution in Wave is read via the Meta integration endpoint. Per- event campaign results, ad insights, and a per-event attribution model selection all live there. For the conceptual model see Attribution concept.

Reading campaign results

GET /integrations/facebook/events/{eid}/campaign_results
GET /integrations/facebook/events/{eid}/fb_insights
Partner scope comes from X-Preferred-Partner-Id — there is no partner_id query parameter. Response (campaign_results):
{
  "event_results":  { "...": "..." },
  "series_results": { "...": "..." }
}
The reference webapp surfaces these on the Statistics tab of the Wave campaign detail page. The tab is disabled when Meta stats are unavailable for this partner / event.
The generic GET /campaign_results/?eid=...&partner_id=... endpoint exists in the OpenAPI spec but is not used by the reference webapp and returns error.auth.not_authorized for non-admin tokens. Read from the Facebook integration endpoint instead.

Switching the attribution model

GET /events/{eid}/attribution_model
PUT /events/{eid}/attribution_model
{ "model": "FD" | "META" | "EXTERNAL" }
Toggling the model refetches both campaign_results and fb_insights — the reference webapp wires this through a shared EventAttributionModelContextProvider that both Lookout and Wave consume. Partner-level default model is read from GET /partners/attribution_model_default. Update via:
PUT /partners/attribution_model?model=FD

Sales adjustments and manual entry

If a partner needs to manually record a sale (e.g. box-office tickets the data feed missed), the reference webapp uses the transaction-summary ingest flow, not POST /campaign_results/:
POST /ingest/transaction_summary
See Lookout — Sales Uploads. Adjustments appear in the daily revenue chart on Lookout’s event detail page (via GET /daily_revenue_summary/’s manual_adjustments array).

Reference implementation

export async function fetchEventResults(eid: string) {
  return fd.get(`/integrations/facebook/events/${eid}/campaign_results`);
}

export async function setAttributionModel(eid: string, model: "FD" | "META" | "EXTERNAL") {
  await fd.put(`/events/${eid}/attribution_model`, { model });
  // Triggers a downstream refetch of campaign_results + fb_insights via
  // your shared attribution-model context.
}

Gotchas

/integrations/facebook/events/{eid}/campaign_results is the one in use. The generic /campaign_results/ is not authorised for partner tokens and returns auth errors.
Partner scope is the X-Preferred-Partner-Id header. Don’t pass partner_id as a query param.
For partners without Meta integration set up, the response can be empty objects. Mirror the reference webapp and disable the tab or show an empty state rather than crash.
Don’t cache campaign_results indefinitely. When the user changes FD / META / EXTERNAL, refetch.