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

# Migrating from v1 to v2

> Guide for upgrading from the v1 Interchange API to v2

# Migrating from v1 to v2

The v2 Interchange API is a fundamental simplification of v1. The surface is smaller, the conventions are agent-first, and the platform now extends across both the buy side and the sell side. v1 is frozen — every integration must migrate to v2. This guide walks you through what changed and how to translate the calls you already use today.

***

## Overview

v2 is a redesign — not a refactor. The core ideas behind Scope3 (allocation over bidding, agentic orchestration, signal-driven media quality) are unchanged. What changed is the API contract.

<CardGroup cols={2}>
  <Card title="Simpler surface" icon="layer-group">
    Single endpoint, single object, full intent (SESOFI). RESTful resources replace v1's per-action verb endpoints.
  </Card>

  <Card title="Agent-first MCP" icon="robot">
    Two generic MCP wrappers — `api_call` and `ask_about_capability` — replace dozens of per-domain MCP tools.
  </Card>

  <Card title="AAO marketplace" icon="store">
    Native support for the Agentic Advertising Organization (AAO) — discover and buy from storefronts.
  </Card>

  <Card title="Measurement engine" icon="chart-line">
    First-class endpoints for hypotheses, test plans, learning cycles, and measurement data ingestion.
  </Card>
</CardGroup>

***

<Warning>
  **v2 is required.** v1 is frozen and will be retired — every integration must move to v2. This guide is the path.
</Warning>

<Tip>
  You can migrate incrementally: v1 and v2 run side by side, so you can move one advertiser, campaign, or workflow at a time rather than cutting over in a single shot.
</Tip>

***

## Key conceptual changes

### Brand Agent → Advertiser

v1 used the term **Brand Agent** as the top-level container for campaigns, creatives, and brand stories. v2 calls this an **Advertiser**. The model is the same, the name is industry-standard.

| v1 term              | v2 term                                                   |
| -------------------- | --------------------------------------------------------- |
| Brand Agent          | Advertiser                                                |
| Brand Agent Standard | Advertiser Standard (rolled into measurement / discovery) |
| Tactic               | Media Buy (already in v1, now consistent)                 |
| Outcome Agent        | Measurement Engine + Hypotheses + Test Plans              |

### MCP tool model: per-domain → generic

In v1, each domain had its own MCP tool — `brand-agent-create`, `campaign-update`, `media-buy-execute`, and so on. Agents had to memorize dozens of tool names and argument shapes.

In v2, every operation goes through one of three generic tools:

| Tool                   | Purpose                                                                                               |
| ---------------------- | ----------------------------------------------------------------------------------------------------- |
| `health`               | Probe API connectivity                                                                                |
| `ask_about_capability` | Ask the API in natural language what it can do — returns operations, fields, and display requirements |
| `api_call`             | Execute any REST endpoint via a named `operation`, with `pathParams`, `body`, and `params`            |

The agent discovers capabilities at runtime via `ask_about_capability` and then dispatches through `api_call`. There is nothing to register, nothing to update when the API gains new operations.

### Skill files

Both buyer and storefront roles ship a skill file that fully describes the API for any agent that can read Markdown:

| Role       | Skill name                           | Skill URL                                               |
| ---------- | ------------------------------------ | ------------------------------------------------------- |
| Buyer      | `scope3-agentic-buyer` (v2.0.0)      | `https://api.interchange.io/api/v2/buyer/skill.md`      |
| Storefront | `scope3-agentic-storefront` (v2.0.0) | `https://api.interchange.io/api/v2/storefront/skill.md` |

Point a custom agent at the skill file and it has end-to-end understanding of the API — operations, required fields, display rules, and workflow guidance.

### New surfaces in v2

| Surface                                | What it is                                                                                            |
| -------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| **Storefronts**                        | Sell-side companion API for inventory owners listing products to buyers                               |
| **Measurement engine**                 | Hypotheses, test plans, learning cycles, belief state, and feedback loops                             |
| **AAO compliance**                     | Native Agentic Advertising Organization (AAO) support — discover and authenticate against storefronts |
| **Partner agents marketplace**         | Browse and connect to third-party signals, sales, and creative agents                                 |
| **Discovery**                          | First-class product discovery with persistent `discoveryId` and proposal application                  |
| **Property lists**                     | Manage allow/block lists at advertiser scope                                                          |
| **Frequency cap & pacing**             | Reusable configs at advertiser level, applied to campaigns and media buys                             |
| **Audit logs / Tasks / Notifications** | Operational visibility for long-running and async operations                                          |

***

## Endpoint mapping

v1 used verb-style RPC paths (`/brand-agent-create`, `/campaign-update`). v2 is fully RESTful with resource-oriented paths under `/api/v2/buyer` and `/api/v2/storefront`.

<Note>
  v2 base URLs (canonical, pinned to v2 — these will keep serving v2 after future major versions):

  * Buyer REST: `https://api.interchange.io/api/v2/buyer`
  * Storefront REST: `https://api.interchange.io/api/v2/storefront`

  The unversioned forms (`/api/buyer`, `/api/storefront`) 308-redirect to whatever major version is currently stable — see [Versioning](/v2/authentication#versioning).

  ADCP property-list resolution lives at the app-level top — `GET /lists/:listId`.
</Note>

### Core resources

| v1 endpoint                                | v2 endpoint                                                     | Notes                                                          |
| ------------------------------------------ | --------------------------------------------------------------- | -------------------------------------------------------------- |
| `POST /brand-agent-create`                 | `POST /advertisers`                                             | Renamed; `brand` field now required                            |
| `POST /brand-agent-update`                 | `PUT /advertisers/{advertiserId}`                               | RESTful update                                                 |
| `POST /brand-agent-list`                   | `GET /advertisers`                                              | Standard list                                                  |
| `POST /brand-agent-get`                    | `GET /advertisers/{advertiserId}`                               |                                                                |
| `POST /brand-agent-delete`                 | `DELETE /advertisers/{advertiserId}`                            |                                                                |
| `POST /campaign-create`                    | `POST /campaigns`                                               | New shape: nested `flightDates`, `budget`, `performanceConfig` |
| `POST /campaign-update`                    | `PUT /campaigns/{campaignId}`                                   |                                                                |
| `POST /campaign-list`                      | `GET /campaigns`                                                | Filter via query params                                        |
| `POST /campaign-get`                       | `GET /campaigns/{campaignId}`                                   |                                                                |
| `POST /campaign-delete`                    | `DELETE /campaigns/{campaignId}`                                |                                                                |
| `POST /campaign-validate-brief`            | (folded into `discover-products`)                               | Brief validation now happens during discovery                  |
| `POST /media-buy-create`                   | (managed via campaigns)                                         | Media buys are created by campaign execution / auto-select     |
| `POST /media-buy-execute`                  | `POST /campaigns/{campaignId}/execute`                          | Execution is now campaign-scoped                               |
| `POST /media-buy-list`                     | `GET /campaigns/{campaignId}/media-buy-status`                  | Returns status for all media buys on a campaign                |
| `POST /signals-list` (v1 partner API)      | `GET /signals` (storefront) / via discovery                     | Signals surface differently per role                           |
| `POST /creative-create`                    | `POST /campaigns/{campaignId}/creatives/create`                 | Creatives are now campaign-nested                              |
| `POST /creative-update` / `delete` / `get` | `PUT/DELETE/GET /campaigns/{campaignId}/creatives/{creativeId}` | RESTful, manifest-based                                        |
| `POST /creative-assign`                    | `GET /campaigns/{campaignId}/creativeManifest`                  | Manifest-driven assignment replaces per-call assign            |
| `POST /tactic-*`                           | (replaced)                                                      | Tactics are subsumed by media buys + allocations               |
| `POST /outcomes-agent-*`                   | `/advertisers/{advertiserId}/hypotheses` etc.                   | Outcome agents become the measurement engine                   |
| `POST /service-token-*`                    | (admin UI / unchanged auth model)                               | Use SSO or API keys; service tokens still work                 |

### v2-only endpoints (no v1 equivalent)

These exist only on v2 and are central to the new platform:

* `POST /discovery/discover-products` and `/discovery/{discoveryId}/...` — persistent product discovery
* `POST /campaigns/{campaignId}/auto-select-products` — AI-driven product selection and budget allocation
* `GET /audit-logs` — full audit trail
* `GET /tasks/{taskId}` — track async operations
* `GET /notifications` (and unread counts via `help` / `ask_about_capability`)
* `GET /storefronts` / `POST /storefronts` (storefront role) — sell-side surfaces
* `/advertisers/{advertiserId}/measurement-config`, `hypotheses`, `test-plans`, `learning-cycle/run`, `belief-state`, `testability` — measurement engine
* `/advertisers/{advertiserId}/property-lists/...` — allow/block lists
* `/advertisers/{advertiserId}/event-sources` and `/measurement-data/sync` — conversion ingestion
* `/advertisers/{advertiserId}/catalogs` and `/syndicate` — partner-agent catalog distribution
* `/accounts/current`, `/accounts`, `/accounts/create-child` — multi-tenant account hierarchy
* `/notification-preferences` and frequency-cap / pacing-period configs

***

## Side-by-side: creating a campaign

<Tabs>
  <Tab title="v1 — brand-agent + campaign">
    ```bash theme={null}
    # Step 1: create the brand agent
    curl -X POST "https://api.interchange.io/v1/brand-agent-create" \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Acme Corp"
      }'

    # Step 2: create the campaign
    curl -X POST "https://api.interchange.io/v1/campaign-create" \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "brandAgentId": "agent_123",
        "name": "Q1 Launch",
        "startDate": "2026-02-05",
        "endDate":   "2026-02-28",
        "budget":    50000
      }'
    ```
  </Tab>

  <Tab title="v2 — advertiser + campaign">
    ```bash theme={null}
    # Step 1: create the advertiser
    curl -X POST "https://api.interchange.io/api/v2/buyer/advertisers" \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "name":  "Acme Corp",
        "brand": "acme.com"
      }'

    # Step 2: create the campaign
    curl -X POST "https://api.interchange.io/api/v2/buyer/campaigns" \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "advertiserId": 24,
        "name":         "Q1 Launch",
        "flightDates":  {
          "startDate": "2026-02-05T00:00:00Z",
          "endDate":   "2026-02-28T23:59:59Z"
        },
        "budget": {
          "total":    50000,
          "currency": "USD"
        },
        "performanceConfig": {
          "optimizationGoals": [
            { "kind": "metric", "metric": "completed_views" }
          ]
        }
      }'
    ```
  </Tab>
</Tabs>

Notable differences:

* `brandAgentId` (string) → `advertiserId` (number)
* `startDate` / `endDate` flat fields → nested `flightDates` object with ISO 8601 datetimes
* `budget: 50000` → nested `budget` object with explicit `currency`
* New optional `performanceConfig.optimizationGoals[]` for goal-based optimization
* Required `brand` field on advertiser create (e.g., `"acme.com"`)

***

## Authentication changes

The bearer-token model from v1 still works in v2. What's new:

<CardGroup cols={2}>
  <Card title="OAuth for AI agents" icon="key" href="/v2/authentication">
    Connect Claude, ChatGPT, and other MCP-aware agents via OAuth. No API keys to manage.
  </Card>

  <Card title="SSO" icon="lock" href="/v2/setup/sso-setup">
    SAML / OIDC SSO for enterprise org sign-in.
  </Card>

  <Card title="AAO OAuth" icon="store">
    Sign in to private / member storefronts via the AAO marketplace using OAuth.
  </Card>

  <Card title="API keys" icon="bolt" href="/v2/authentication">
    Same `Bearer scope3_...` format as v1 — your existing keys keep working.
  </Card>
</CardGroup>

<Tip>
  If you only use API keys today, no auth changes are required. Just point your existing key at the v2 base URL.
</Tip>

***

## Breaking changes checklist

When you migrate, audit for these:

* [ ] **Path style** — every v1 verb endpoint (e.g. `/campaign-create`) maps to a RESTful resource (e.g. `POST /campaigns`)
* [ ] **`brandAgentId` → `advertiserId`** — and the type changed from string to number
* [ ] **Date fields** — flat `startDate` / `endDate` are now nested under `flightDates` with required ISO 8601 datetimes (with `Z` suffix)
* [ ] **Budget** — scalar `budget: 50000` is now an object with `total` and `currency`
* [ ] **Required `brand`** — advertiser create now requires a brand domain (e.g. `"acme.com"`)
* [ ] **Creatives** — now nested under `/campaigns/{campaignId}/creatives` and use a manifest model rather than per-call assign
* [ ] **Tactics** — removed as a top-level concept; functionality lives in media buys + allocations
* [ ] **Outcome agents** — replaced by the measurement engine (hypotheses, test plans, learning cycles)
* [ ] **MCP tools** — per-domain v1 tools are not available in v2; use `api_call` + `ask_about_capability`
* [ ] **Field naming** — v2 is strict camelCase. `advertiser_id` is rejected; use `advertiserId`. `flight_dates` is rejected; use `flightDates`.
* [ ] **Optimization goals** — now live on `performanceConfig.optimizationGoals[]` with `kind: "event" | "metric"`. Valid `metric` values: `clicks`, `views`, `completed_views`, `viewed_seconds`, `attention_seconds`, `attention_score`, `engagements`, `follows`, `saves`, `profile_visits`, `reach`. `impressions` is a delivery rollup, not a valid optimization target.
* [ ] **Creative assignment** — done via `creativeManifest` rather than per-creative `creative-assign` calls

***

## Skill / MCP migration

If your v1 integration drove the API through per-domain MCP tools, you'll dispatch through the generic v2 tools instead.

<Tabs>
  <Tab title="v1 — per-domain tool">
    ```jsonc theme={null}
    // MCP tool call: brand-agent-create
    {
      "name": "brand-agent-create",
      "arguments": {
        "name": "Acme Corp"
      }
    }
    ```
  </Tab>

  <Tab title="v2 — generic api_call">
    ```jsonc theme={null}
    // MCP tool call: api_call with named operation
    {
      "name": "api_call",
      "arguments": {
        "operation": "create_advertiser",
        "body": {
          "name":  "Acme Corp",
          "brand": "acme.com"
        }
      }
    }
    ```
  </Tab>
</Tabs>

The recommended pattern for any v2 agent:

<Steps>
  <Step title="Discover the operation">
    Call `ask_about_capability` with a natural-language description of what you want to do. The response lists candidate operations, required fields, display requirements, and workflow notes.
  </Step>

  <Step title="Verify every field has a source">
    Walk every field in `body`, `pathParams`, and `params` and name where it came from — a previous response, the user, or `ask_about_capability`. Never invent IDs or fabricate values.
  </Step>

  <Step title="Dispatch via api_call">
    Pass `operation`, `pathParams`, `body`, and `params` to `api_call`. The named `operation` enum prevents hallucinated endpoints and wrong HTTP methods.
  </Step>

  <Step title="Present results per the display rules">
    Each operation's `ask_about_capability` response describes what to show the user (status, IDs, account links, sandbox flag, etc.). Show those fields — never collapse to vague prose.
  </Step>
</Steps>

Use the buyer MCP endpoint and canonical storefront agent URL below:

| Role       | URL                                    |
| ---------- | -------------------------------------- |
| Buyer      | `https://api.interchange.io/mcp/buyer` |
| Storefront | `https://interchange.io`               |

***

## Sandbox

v2 has first-class sandbox support. Set `"sandbox": true` when creating an advertiser and every ADCP operation under that advertiser routes to sandbox accounts — no real spend, no production side effects.

<Card title="Sandbox guide" icon="flask" href="/v2/features/sandbox">
  Learn how to test campaigns, discovery, and media-buy flows safely.
</Card>

<Warning>
  The `sandbox` flag is **immutable** after the advertiser is created. Decide up front whether the advertiser is for production or testing.
</Warning>

***

## Getting help

<CardGroup cols={3}>
  <Card title="Quick Start" href="/v2/quickstart" icon="rocket">
    Connect an agent and make your first call in minutes.
  </Card>

  <Card title="API Reference" href="/v2/buyer-api-reference" icon="code">
    Browse every v2 endpoint with request and response schemas.
  </Card>

  <Card title="Authentication" href="/v2/authentication" icon="key">
    OAuth, SSO, and API key setup.
  </Card>

  <Card title="Built for Agents" href="/v2/setup/built-for-agents" icon="robot">
    Detailed setup for Claude, ChatGPT, Cursor, and custom agents.
  </Card>

  <Card title="Skill File" href="/v2/skill" icon="file-code">
    Why a skill file beats hand-written tool wrappers.
  </Card>

  <Card title="Support" href="mailto:support@scope3.com" icon="envelope">
    Email [support@scope3.com](mailto:support@scope3.com) for migration help.
  </Card>
</CardGroup>
