> ## 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.

# Campaigns on connected provider accounts

> Mirror and inspect campaigns from a connected provider account

<Note>
  Provider-account campaign mirroring is available to buyers with an eligible
  connected account. It is read-only: Apostra does not create,
  update, pause, reactivate, or cancel campaigns in the connected account.
</Note>

## Tracked campaigns

Connecting a provider account lets Apostra materialize its campaigns as
read-only, `management: "tracked"` projections. The connected provider remains
the source of truth. Apostra periodically reconciles the
projection and provides shared identity, audit, relationship rollups, and live
delivery access around it.

The compatibility API value for these projections is `mode: "directed"`.
`directed` is a deprecated wire discriminator, not a product name. Use the
`management` field to understand who operates a campaign:

* `management: "tracked"` means it was mirrored from provider-account
  activity that Apostra did not author. The projection is read-only.
* `management: "managed"` means the campaign uses the canonical Apostra
  buyer lifecycle. Discover products and create, read, update, pause, or cancel
  its media buys through the buyer media-buy APIs.

Each tracked campaign is a one-to-one projection of one storefront campaign
and one upstream AdCP media buy. Its name, status, flight, budget, and packages
come from that buy and cannot be edited independently. The projection preserves
both Apostra's `media_buy_id` and the storefront's `adcp_media_buy_id`.

Tracked campaigns return
`directed.provenance: "connected_account"` with connection/account IDs,
provider, mirror freshness, and upstream media-buy identity.

## Connect and subscribe an account

First [connect the official adapter](/v2/guides/connecting-ad-platforms) and
[map its discovered account to an advertiser](/v2/concepts/ad-platform-accounts#after-connecting).
For an agent-driven setup:

1. Call `list_storefronts`, then `connect_storefront` to obtain the human OAuth
   handoff URL.
2. Call `list_storefront_connections` and
   `list_storefront_connection_accounts` to choose a buyable account.
3. Read `list_storefront_connection_account_mappings`. If needed, call
   `map_storefront_connection_account_to_advertiser` with the intended
   advertiser.
4. Call `subscribe_directed_campaigns` with the mapped connection and account
   IDs to start the read-only mirror.

Organization/manager and publisher-identity accounts cannot be subscribed.

```bash theme={null}
curl -X POST \
  "https://api.apostra.com/api/v2/buyer/storefront-connections/42/accounts/81/directed-campaigns/subscribe" \
  -H "Authorization: Bearer $SCOPE3_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "advertiserId": "12345"
  }'
```

Subscription immediately attempts a metadata sync. Active campaigns are
always included; terminal history is backfilled for one year by default.
Subsequent worker sweeps reconcile changes every 15 minutes by default. This
does not import delivery history.

The response includes `backfillStart`, `lastSyncedAt`, `lastSyncStatus`,
`lastSyncError`, and mirrored/retired/skipped counts. Read the same state later
with:

```text theme={null}
GET /api/v2/buyer/storefront-connections/{connectionId}/accounts/{accountId}/directed-campaigns/subscription
```

`backfillStart` is a fixed metadata-history boundary, not a progress meter. A
subscription remains durable when enumeration is unsupported or temporarily
unhealthy; the status reports `ERROR` and the worker retries. Existing valid
mirrors survive a failed or incomplete snapshot.

When a broad account read omits a known nonterminal campaign, Apostra
performs a bounded direct read before retiring its projection. A complete
terminal response preserves campaign and package history even if the provider
returns no packages. A failed or incomplete direct read retains the last valid
mirror.

To stop mirroring, call `unsubscribe_directed_campaigns`. Apostra pauses
the sweep and retires local projections; it does not delete upstream campaigns.

### Registered AdCP storefront sources

A buyer may project a registered third-party AdCP storefront source
into the same connection plane. Register source credentials, discover the
source account with `list_available_accounts`, map it to an advertiser, then
call `connect_adcp_storefront`:

```bash theme={null}
curl -X POST \
  "https://api.apostra.com/api/v2/buyer/storefronts/42/sources/publisher-sales/adcp-connection" \
  -H "Authorization: Bearer $SCOPE3_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "advertiserId": "12345",
    "accountId": "provider-account-7",
    "credentialId": "81"
  }'
```

The response returns `connectionId` and `connectionAccountId`; use them with
the normal subscribe, subscription-status, campaign-read, and delivery-read
operations. The operation accepts only sources already registered on an active
storefront. It never accepts an arbitrary endpoint URL or raw secret.

For registered sellers, a snapshot is complete only when every requested page
returns boolean `pagination.has_more`, every cursor advances, every buy carries
a valid ISO currency, and any returned account ID matches the pinned account.
Incomplete snapshots never retire an existing projection.

## List and inspect mirrors

Use the shared campaign surface and compatibility mode filter:

```bash theme={null}
curl \
  "https://api.apostra.com/api/v2/buyer/campaigns?mode=directed&advertiserId=12345" \
  -H "Authorization: Bearer $SCOPE3_API_KEY"
```

`GET /api/v2/buyer/campaigns/{campaignId}` returns the tracked campaign and its
single mirrored media buy. Discovery, execute, pause, reactivate, and ordinary
campaign mutations reject tracked projections.

To prioritize a fresh upstream snapshot without changing the provider account, send the
refresh-only compatibility request:

```json theme={null}
{ "mode": "directed", "refresh": true }
```

### Meta: observed automation controls during refresh

Tracked Meta campaigns that use Advantage+ audience targeting can return
provider-observed automation controls during refresh. The Meta adapter validates
and retains those controls in its provider readback evidence so a known control
does not make the complete refresh fail as unsupported. The shared directed
campaign response does not expose raw Meta automation controls, and they do not
appear in the package's canonical `targeting_overlay` or grant write
authorization. The tracked surface remains read-only, and the values reflect
provider state rather than an Apostra-authored targeting decision.

Active `individual_setting` controls are reported only when `advantage_audience: 1`
is also present; an active individual control without the automation anchor is not
representable and causes the upstream read or refresh to fail closed. All other
active automation dimensions (e.g. `creative_audience_pairing`) and any
malformed or unrecognized values are likewise not representable. Adapter-created
packages with an expected ledger use full durable product/request/confirmation
authorization rather than provider-observed readback.

## Relationship rollup

Scale lives on the provider-account relationship rather than the default
campaign list. Each account may return a `campaignRollup`:

| Field              | Meaning                                                                            |
| ------------------ | ---------------------------------------------------------------------------------- |
| `campaignsTracked` | Non-retired tracked campaigns on the account                                       |
| `campaignsActive`  | Tracked campaigns currently active                                                 |
| `trackedSpend`     | Provider-reported delivered spend across tracked campaigns in the trailing window  |
| `managedSpend`     | Delivered spend across canonical Apostra-managed campaigns in the trailing window  |
| `managedShare`     | `managedSpend / (trackedSpend + managedSpend)`; `null` when no spend was accounted |
| `currency`         | Account ISO 4217 currency                                                          |
| `windowDays`       | Trailing aggregation window                                                        |

Money never rolls up across accounts because accounts on one connection may
use different currencies.

## Presences: audiences and event sources

Connected accounts may expose first-party audiences and event sources as
account presences. Use
`GET /api/v2/buyer/storefront-connections/{connectionId}/accounts/{accountId}/presences`
or `list_account_presences`. This is a read-only discovery surface; it does not
sync an audience or authorize a provider mutation.

## Read delivery through the provider

Use the normal campaign delivery endpoint:

```bash theme={null}
curl \
  "https://api.apostra.com/api/v2/buyer/campaigns/cmp_123/delivery?startDate=2026-01-01&endDate=2026-07-10" \
  -H "Authorization: Bearer $SCOPE3_API_KEY"
```

Each call reads through to the connected provider's
`get_media_buy_delivery`. Raw payloads and time series are not cached. Only the
latest aggregate media-buy/package metrics, exact requested window, and refresh
time are persisted. Subscription and metadata sweeps never pull delivery.

If dates are omitted, the read requests the one-year window through yesterday.
Provider window limits may cause Apostra to split the request into
consecutive chunks before merging aggregate results.

## Errors and recovery

* Account or mapping not found: re-list the official connection and discovered
  accounts, then use only returned IDs.
* `lastSyncStatus: "ERROR"`: inspect safe `errorCode`, `errorField`,
  `errorReason`, and `upstreamCode` fields. Reconnect only for authentication or
  authorization failures; retry provider-shape or availability failures.
* `mirrored: 0` with successful sync is an empty eligible history window, not a
  failed backfill.

## Boundaries

* The tracked-campaign surface is subscription, mirror, refresh, presence,
  relationship-rollup, and delivery read-only.
* Campaigns created or managed through Apostra use the canonical buyer
  product and media-buy lifecycle, not a tracked-campaign write path.
* Change webhooks, scheduled delivery/export, invoice-grade reporting, and
  BigQuery delivery history are not part of tracked-campaign mirroring.
* Availability never subscribes an account and never grants authority to
  mutate its campaigns.
