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

# Create measurement source

> Register an MMM, brand-lift, or partner data source for an advertiser

`POST /api/v2/buyer/advertisers/{advertiserId}/measurement-sources`

Registers a measurement data source (e.g. an MMM model or brand-lift study) for an advertiser. The source defines which outcome type it produces, how often, and the lag before data lands — the engine uses these to weigh incoming records and check freshness.

## Request

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://api.apostra.com/api/v2/buyer/advertisers/12345/measurement-sources \
    -H "Authorization: Bearer $SCOPE3_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "sourceKey": "acme_incr_rev",
      "name": "Acme Incrementality",
      "outcomeType": "incremental_revenue",
      "granularity": "geo_week",
      "cadence": "weekly",
      "provider": "acme-mmm",
      "lagWeeks": 1,
      "signalWeight": 1,
      "status": "active"
    }'
  ```
</CodeGroup>

## Parameters

| Field | Type | Required | Notes |
| - | - | - | - |
| `advertiserId` | string | Yes | Path parameter — the owning advertiser |
| `sourceKey` | string | Yes | Stable key tying records to this source |
| `name` | string | Yes | Human-readable label |
| `outcomeType` | string | Yes | Primary outcome the source reports |
| `granularity` | string | Yes | Reporting grain (e.g. `geo_week`) |
| `cadence` | enum | Yes | `continuous`, `daily`, `weekly`, `biweekly`, `monthly`, `quarterly` |
| `provider` | string | Yes | Partner name (e.g. `acme-mmm`) |
| `outcomeTypes` | string\[] | No | Additional outcome types the source reports |
| `lagWeeks` | integer | No | Expected reporting lag in weeks (default 1) |
| `ingestionMethod` | string | No | How records arrive (e.g. `api`, `sync`) |
| `attributionConfig` | object | No | Free-form provider attribution settings |
| `signalWeight` | number | No | Weight in belief updates, 0–1 (default 1) |
| `status` | enum | No | `pending`, `active`, `paused` (default `pending`) |
| `notes` | string | No | Free-text notes |
| `vendor` | object | No | The measurement vendor as AdCP identifies it: `domain` (the domain hosting the vendor's `brand.json`, e.g. `placer.ai`) and optional `brandId` |
| `vendorMetrics` | object\[] | No | Vendor metrics this source reports, up to 50. Each is `{ metricId, outcomeType }`: the vendor's AdCP metric id and the outcome type this source's records carry for it. Requires `vendor` |

## Response

```json theme={null}
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "advertiserId": "12345",
  "sourceKey": "acme_incr_rev",
  "name": "Acme Incrementality",
  "outcomeType": "incremental_revenue",
  "outcomeTypes": [],
  "granularity": "geo_week",
  "cadence": "weekly",
  "provider": "acme-mmm",
  "lagWeeks": 1,
  "signalWeight": 1,
  "status": "active",
  "vendor": null,
  "vendorMetrics": [],
  "createdAt": "2026-01-15T10:30:00Z",
  "updatedAt": "2026-01-15T10:30:00Z"
}
```

### Name the vendor and its metrics

`provider` is a free-text label. When the source is a measurement vendor that sellers and goals can refer to, also send `vendor` and `vendorMetrics`. Sellers identify a vendor metric by the vendor's domain and the metric id, so this is what lets a goal later be counted by this source. Each metric maps to one of the source's outcome types; records you upload under that outcome type count as that vendor metric.

```json theme={null}
{
  "sourceKey": "placer_store_visits",
  "name": "Placer store visits",
  "outcomeType": "foot_traffic",
  "granularity": "store_week",
  "cadence": "weekly",
  "provider": "placer",
  "vendor": { "domain": "placer.ai" },
  "vendorMetrics": [{ "metricId": "store_visits", "outcomeType": "foot_traffic" }]
}
```

The returned `id` is the `sourceId` you pass to [Get](/v2/buyer/measurement/tasks/get-measurement-source) and [Update](/v2/buyer/measurement/tasks/update-measurement-source).

## Errors

* `400 VALIDATION_ERROR` — missing a required field, invalid `cadence`/`status`, or `signalWeight` outside 0–1.
* `400 VALIDATION_ERROR` — `vendorMetrics` sent without `vendor`, a `metricId` listed twice, or a metric mapped to an outcome type that is neither `outcomeType` nor in `outcomeTypes`.
* `404 NOT_FOUND` — `advertiserId` does not exist or is not visible to the authenticated account.

See [Errors](/v2/reference/errors) for the full error contract.

## Related

<CardGroup cols={2}>
  <Card title="Measurement tasks" href="/v2/buyer/measurement/tasks" icon="list-check">
    All measurement operations
  </Card>

  <Card title="Measurement overview" href="/v2/guides/measurement-incrementality" icon="chart-line">
    Pipeline, belief state, and concepts
  </Card>

  <Card title="List measurement sources" href="/v2/buyer/measurement/tasks/list-measurement-sources" icon="list">
    See registered sources
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.