Unified.to
All articles

Build Cross-Platform Campaign Controls (Status, Budgets, Flight Dates) with Unified Advertising API


February 13, 2026

Most advertising control features break at the same point: provider inconsistency.

Pausing a campaign, increasing a budget, or extending a flight window should be straightforward. In practice, each advertising platform differs:

  • Which campaign fields are writable
  • Whether budgets can be changed after launch
  • Whether start and end dates are editable
  • How errors are returned
  • Which scopes are required

If you integrate directly against Google Ads, Meta Ads, TikTok Ads, LinkedIn Ads, and DV360, you maintain separate code paths per provider.

Unified's Advertising category provides a unified API surface for campaign control across supported platforms, while maintaining a real-time, pass-through architecture with no data storage .

This guide shows how to implement:

  • Pause / resume
  • Budget adjustments
  • Flight date updates
  • Provider-safe error handling
  • Production-safe retry logic

Using the official TypeScript SDK.

Prerequisites

1. Advertising connection

Create an Advertising connection with:

  • Category: ADS
  • Required scopes:
    • ads_campaign_read
    • ads_campaign_write
    • ads_organization_read

Unified allows requesting scopes via the Authorization component or via an auth URL. If scopes are omitted, Unified attempts to request all available scopes, but explicit scope selection is recommended .

2. Discover ad accounts (Organizations)

Ad account selection does not occur during OAuth.

After connecting:

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

Each AdsOrganization includes:

  • id
  • name
  • currency
  • timezone

You may optionally pass orgId when listing campaigns to filter by ad account.

3. List campaigns

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

orgId is a filter parameter. It is not required for updates.

Campaign Control Pattern (PUT Semantics)

The SDK exposes:

updateAdsCampaign

This performs a PUT operation.

To avoid unintentionally clearing fields, use a read → merge → update pattern.

1. Pause or Resume a Campaign

import { UnifiedTo } from '@unified-api/typescript-sdk';

const sdk = new UnifiedTo({
  security: { jwt: process.env.UNIFIED_API_KEY! },
});

const connectionId = '5de520f96e439b002043d8dc';
const id = '1234'; // campaign id

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

// 2) Update status
await sdk.ads.updateAdsCampaign({
  connectionId,
  id,
  adsCampaign: {
    ...current,
    status: 'PAUSED',
  },
});

To resume:

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

Provider support

Campaign status updates are supported across major advertising integrations.

If unsupported for a provider, Unified returns:

501 Not Implemented
"The requested functionality is not supported by this integration"

Unsupported fields are rejected, not ignored.

2. Update Campaign Budgets

Budget fields:

budgetAmount?: number;
budgetPeriod?: 'DAILY' | 'MONTHLY' | 'TOTAL' | 'LIFETIME';

Example: Increase daily budget

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

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

Provider variability

Budget write support differs by platform.

Before enabling budget controls in your UI:

  • Detect provider type
  • Confirm writable fields
  • Disable unsupported controls

Attempting to update unsupported fields results in a 501 response.

3. Update Flight Dates

Date fields must be ISO-8601:

YYYY-MM-DDTHH:MM:SSZ

Example: Extend campaign end date

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

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

Provider variability

Some platforms do not allow modifying flight dates after launch.

Your application should:

  • Catch 501 errors
  • Surface clear UI messaging
  • Avoid retrying unsupported operations

Error Handling in Production

Unified returns standard HTTP codes.

400 — Validation error

Returned when:

  • Required fields missing
  • Invalid date format
  • Invalid enum value

401 / 403 — Scope or authorization error

Occurs when:

  • OAuth token invalid
  • Required write scope not granted

429 — Rate limit exceeded

Returned when:

  • Provider limit reached
  • Unified platform limit reached

Implement exponential backoff:

  • Retry only on 429
  • Add jitter
  • Cap retries
  • Log failures

The SDK does not automatically retry write calls.

501 — Unsupported functionality

Returned when:

  • Field is not writable for the provider

Do not retry 501 responses.

Provider-Safe Update Pattern

In production:

  1. Retrieve campaign
  2. Merge only intended changes
  3. Submit update
  4. Catch and classify errors
  5. Retry only on 429

This prevents accidental field overwrites and avoids unsafe retry behavior.

Why This Architecture Matters

Unified's Advertising category operates with:

  • Real-time reads and writes
  • Pass-through requests
  • No storage or caching
  • Usage-based pricing aligned with scale

This eliminates:

  • Per-provider integration logic
  • Separate OAuth implementations
  • Separate retry pipelines
  • Cached or delayed state

Normalized campaign objects remove per-provider mapping logic and reduce maintenance overhead .

For product teams, this means:

  • Faster delivery of campaign controls
  • Cleaner UI consistency
  • Reduced engineering maintenance
  • Predictable infrastructure cost

Complete Example Flow

// 1. List organizations
const orgs = await sdk.ads.listAdsOrganizations({ connectionId });

// 2. Select organization
const orgId = orgs[0].id;

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

// 4. Retrieve campaign
const campaign = await sdk.ads.getAdsCampaign({
  connectionId,
  id: campaigns[0].id!,
});

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

No per-provider branching required in your integration logic. Only provider capability checks for writable fields.

Why This Matters

Campaign controls appear simple but become complex at scale.

Unified's Advertising category gives you:

  • A unified API surface per category
  • Real-time read/write behavior
  • Explicit provider capability handling
  • Production-safe error semantics
  • No stored customer data

You can implement pause/resume, budget updates, and flight adjustments across supported advertising platforms without maintaining separate integrations per provider.

That is infrastructure, not integration maintenance.

→ Start your 30-day free trial

→ Book a demo

All articles