Unified.to
All articles

How to Build an Advertising Dashboard Across Multiple Platforms Using a Unified Advertising API


March 24, 2026

An advertising dashboard shows campaign performance across multiple integrations and allows users to act on that data.

In practice, this is not just a reporting problem. It is a campaign structure and targeting problem.

Each advertising integration defines:

  • campaign structure differently
  • targeting inputs differently
  • identifiers differently
  • write behavior differently

This guide shows how to build a cross-platform advertising dashboard that:

  • retrieves campaigns and performance data
  • segments by ad account
  • looks up targeting identifiers
  • updates campaigns (status, budgets, dates)
  • applies targeting at the correct level

Using the Unified Advertising API.

Why Advertising Dashboards Break

Most teams start with reporting:

  • fetch campaigns
  • fetch metrics
  • display charts

This works for one integration.

It breaks when you support multiple:

  • targeting identifiers are incompatible
  • campaign fields behave differently
  • some integrations allow updates, others don't
  • filtering logic becomes inconsistent

The result:

  • inconsistent UI
  • fragile logic
  • increasing maintenance

The issue is not metrics.

The issue is campaign structure + targeting.

How the Advertising Data Model Works

Unified provides a consistent structure across integrations.

ObjectPurposeKey Fields
OrganizationAd accountid, name, currency
CampaignBudget + schedulestatus, budget, dates
GroupTargeting + deliverytargeting, bid
AdCreativeheadline, copy
TargetLookup valuesid, name, type
ReportMetricsmetrics

Targeting is:

  • readable on campaigns
  • configurable primarily at the group level
  • supported at campaign level only where the integration allows it

Step 1: Retrieve Ad Accounts

Ad accounts are represented as AdsOrganization.

const organizations = await sdk.ads.listAdsOrganizations({
  connectionId,
});

Each organization includes:

  • id
  • name
  • currency
  • timezone

Ad account selection happens after authorization, not during OAuth.

Step 2: Retrieve Campaigns

const campaigns = await sdk.ads.listAdsCampaigns({
  connectionId,
  orgId, // optional
});

Key points:

  • orgId filters by ad account
  • campaigns are returned using a unified structure
  • targeting is included as a readable field

Step 3: Retrieve Performance Data

const reports = await sdk.ads.listAdsReports({
  connectionId,
  startGte: "2026-01-01",
  endLt: "2026-01-31",
});

Each report includes:

  • organization_id
  • start_at, end_at
  • metrics[]

Metrics are integration-defined and should not be hardcoded.

Step 4: Look Up Targeting Identifiers

Before applying targeting, you must retrieve valid IDs.

Each integration uses different identifiers:

Unified provides a lookup endpoint:

const targets = await sdk.ads.listAdsTargets({
  connectionId,
  type: 'countries',
  query: 'united',
  limit: 50,
});

Returns:

[
  { "id": "US", "name": "United States", "type": "countries" },
  { "id": "GB", "name": "United Kingdom", "type": "countries" }
]

Supported types include:

  • countries, regions, cities
  • locales, languages
  • interests, behaviors, topics
  • user_lists (custom audiences)
  • age_ranges, genders

These IDs are used in targeting payloads.

Step 5: Apply Targeting (Group-Level)

For most integrations, targeting is configured at the group level.

const group = await sdk.ads.getAdsGroup({
  connectionId,
  id: groupId,
});

await sdk.ads.updateAdsGroup({
  connectionId,
  id: groupId,
  adsGroup: {
    ...group,
    targeting: {
      geographic: {
        countries: ['US'],
        regions: [{ id: '3843', name: 'California' }],
      },
      demographic: {
        ageMin: 25,
        ageMax: 54,
        male: true,
        female: true,
      },
      audience: {
        interests: [
          { id: '600313926646746', name: 'Technology' }
        ],
      },
    },
  },
});

Important:

  • IDs come from listAdsTargets
  • targeting structure is consistent
  • available targeting types vary by integration

Step 6: Update Campaign Controls

Campaign updates use PUT semantics.

Use a read → merge → update pattern.

Pause a campaign

const campaign = await sdk.ads.getAdsCampaign({
  connectionId,
  id,
});

await sdk.ads.updateAdsCampaign({
  connectionId,
  id,
  adsCampaign: {
    ...campaign,
    status: 'PAUSED',
  },
});

Update budget

await sdk.ads.updateAdsCampaign({
  connectionId,
  id,
  adsCampaign: {
    ...campaign,
    budgetAmount: 5000,
    budgetPeriod: 'DAILY',
  },
});

Update flight dates

await sdk.ads.updateAdsCampaign({
  connectionId,
  id,
  adsCampaign: {
    ...campaign,
    endAt: '2026-03-31T23:59:59Z',
  },
});

Dates must be ISO-8601.

Provider Differences You Must Handle

Not all integrations support the same fields.

Examples:

  • Some allow campaign-level targeting
  • Most require group-level targeting
  • Some do not allow budget updates
  • Some restrict date changes

When unsupported:

501 Not Implemented

Do not retry these operations.

Rate Limits and Retry Logic

When rate limits are exceeded:

429 Too Many Requests

Recommended approach:

  • exponential backoff
  • retry only on 429
  • avoid retrying validation errors

The SDK does not automatically retry write operations.

How the Dashboard Comes Together

The full data flow:

organizations
→ campaigns
→ reports
→ targets (lookup)
→ groups (targeting)
→ campaign updates

This allows you to:

  • display campaigns across integrations
  • compare performance
  • segment by ad account
  • apply targeting consistently
  • update campaigns safely

Why Targeting Is the Hardest Part

Campaign metrics are easy to retrieve.

Targeting is not.

Each integration:

  • uses different identifiers
  • supports different targeting types
  • validates inputs differently

Without a lookup layer, you must:

  • build mapping logic per integration
  • maintain ID dictionaries
  • handle edge cases manually

Unified removes that step by providing:

  • a targeting lookup endpoint
  • a consistent targeting structure
  • unified object models

This reduces per-integration logic and simplifies campaign creation.

Key Takeaways

  • Advertising dashboards fail due to targeting and campaign structure differences
  • Campaigns handle budget and scheduling
  • Groups handle targeting for most integrations
  • Targeting IDs must be retrieved using listAdsTargets
  • Campaign updates require read → merge → update
  • Provider support varies and must be handled explicitly
  • Targeting is the highest-friction part of campaign management

Start your 30-day free trial

Book a demo

All articles