> ## Documentation Index
> Fetch the complete documentation index at: https://docs.semicola.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Set up an event source

> Use when a buyer campaign needs conversion measurement: find or create the advertiser's event source and confirm events are arriving.

Skill `set-up-an-event-source` · version 1.0.0 · for buyers.

## When to use

* A person wants a campaign to optimize for purchases, leads or another conversion.
* A person asks whether their site is sending conversion events.
* [Set up a campaign](/skills/set-up-a-campaign) found a conversion goal in the brief.

## Before you start

* You are connected to the buyer account and know the `advertiserId`.
* You know which conversions matter to the person and on which domains they happen.
* Someone who can change the advertiser's website or app is available to install the tag.

## Steps

1. Call `get_status` and confirm the account and advertiser.
2. Call `search` with `kind: "measurement_source"`, `filter.advertiserId`, and the person's words as
   `query` (it matches the name, `eventSourceId` and integration platform). Reuse an event source that
   already covers the advertiser.
3. Call `get` with `kind: "measurement_source"`, the source's `id` (it begins with `event:`) and the
   `advertiserId`. Read its event types, allowed domains and health: `not_seen`, `receiving` or
   `needs_attention`.
4. If there is no suitable source, confirm the event types and allowed domains with the person,
   then call `save_measurement_source` with `sourceType: "event"`, a stable `eventSourceId` of your
   choosing, a clear `name`, the exact `eventTypes`, and `integrationPlatform` set to the system that
   will send the events (the person's server, CRM or measurement partner). Or call `open_page` with
   `page: "event_sources"` and the `advertiserId` in `arguments` so the person creates it there.
5. The person's server sends events: the **Event sources** page shows a server-side snippet and a
   **Send test event** button. From an agent, `log_event` sends events to the source; only send real
   events the person gives you, never invented ones.
6. Call `get` on the source again until its health is `receiving`. If it stays `not_seen` or turns
   `needs_attention`, tell the person what the page reports.
7. If the person wants the campaign to optimize for the conversion, read the campaign first, then
   call `save_campaign` with `optimizationGoals`: an event goal whose `eventSources` entry names the
   source's `eventSourceId` (its key, not the `event:` id) and an event type the source sends (another
   type is refused with `unsupportedEventTypes`). Send the whole ranked list
   (primary first); `null` removes every goal. An unknown key is refused with
   `unknownEventSourceIds`. If the person goes ahead without tracking, leave the goal out and say the
   campaign won't optimize for that outcome.
8. Tell the person what happens next: when the campaign sends a buy to a seller, Semicola registers
   the source on that seller and the goal goes with the seller's own id.
   `GET /api/v2/buyer/event-sources?advertiserId=…` lists each seller in `sellerProvisioning`:
   `provisioned`, `needs_install`, `unsupported` or `failed`. A goal whose source isn't `provisioned`
   on a seller is left out of that seller's buy. Changing the goals on a live campaign sends them to
   its live buys too (`optimizationGoalsCascadeResult` in the response).
9. If the advertiser needs an integration Semicola does not offer yet, file it with `save_ask` and
   `type: "integration"`.

## Guardrails

* Never send or ask for personal data about the people behind the events.
* Do not say events are arriving until the health says `receiving`.
* Missing conversions are unavailable, not zero.
* Never attach a guessed or unregistered `eventSourceId` to a goal.
* Don't promise attribution or conversion reporting: Semicola counts events and forwards them to
  sellers the source is provisioned on; each seller does its own optimization.
* **Send test event** sends test traffic (`testEventCode`): validated, never counted as a conversion,
  and it doesn't change the health. Use `testEventCode` on `log_event` only for test events.

## Done when

* The event source reports `receiving`.
* The campaign carries the event goal (or the person chose to go without one), and the brief states
  the conversion goal.
* The person knows which events are counted and where to check health later.
