POST /api/v2/buyer/campaigns
For discovery and performance, creates a campaign in DRAFT status for the
given advertiser. You set flight dates and budget up front; products, creatives,
and audiences attach afterward. Routing (DECISIONED vs ROUTED) is not a
campaign input — it is derived per media buy from the storefront it executes
against. Execute the campaign later to turn it into live media buys.
For the separately enrolled directed-write alpha, the same endpoint forwards one
explicit AdCP media buy to a mapped, subscribed connection and projects the result
as a directed campaign. A directed campaign has no DRAFT planning or execute step.
Every campaign budget is GROSS: budget.total is the all-in amount the buyer pays, with the Scope3 fee inside it. Every budget downstream is gross too — media buy and package budgets allocate against budget.total directly, and the media/fee split is derived per media buy at the fee terms locked when that buy is created (readable via its budget_breakdown — see Budgets and fees). There is no fee-model input at creation — the campaign object has no feeType field.
Request
Parameters
The table below describes platform-managed creation. See Directed campaigns for the strictmode: "directed" branch.
| Field | Type | Required | Notes |
|---|---|---|---|
advertiserId | number | Yes | Owning advertiser |
name | string | Yes | Campaign name (max 255) |
flightDates | object | Yes | { startDate, endDate }, ISO 8601 dates |
budget | object | Yes | { total, currency?, dailyCap?, pacing? }. currency defaults to the advertiser’s primary currency when omitted. pacing is EVEN, ASAP, or FRONTLOADED |
brief | string | No | Free-text plan brief used to guide product selection |
constraints | object | No | channels filter plus AdCP targeting overlay: geo_countries, geo_metros, language. Send only metro codes in geo_metros; use resolve_targeting_dimension when the buyer provides a name such as “LA DMA”, and request fields=geo_metro_names on campaign reads when display labels are needed. Included labels return in geo_metro_names; excluded labels return in geo_metro_names_exclude. |
pacingPeriods | object | No | Time-windowed pacing. mode is weight or budget; periods[] each carry label, start, end, and weight (weight mode) |
Directed request (alpha)
A directed create requiresmode, advertiserId, connectionId, accountId,
name, a 16–255 character root idempotencyKey, root currency, and an
explicit mediaBuy. The subscription must carry matching currency and
per-buy/account governance caps, and the customer must have both directed read
and write flags. brief, flightDates, campaign-level budget, and nested
account/idempotency_key fields are validation errors.
TikTok’s first write canary requires mediaBuy.paused: true and rejects creative
assignments or inline creatives. Use future dates as an additional precaution.
The media buy contains the AdCP brand, total_budget, and explicit
packages; use only product and pricing-option IDs returned by
list_directed_campaign_products
for this connected account. See the directed-campaign guide for a complete request.
Response
status: "DRAFT". campaign.campaignId is the stable identifier you pass to every sibling operation. Routing is decided per media buy at execution time — a campaign has no routing type of its own. When the request included a discoveryId, the response also carries productGroups, budgetContext, and summary from the discovery session.
For a directed create that reconciles synchronously, the response is
{ campaign, directedWrite }; directedWrite.status is CONFIRMED and the
campaign is the provider-backed projection, not a DRAFT shell. If provider
enumeration has not proved the new object yet, the endpoint returns 202 Accepted with the raw directed write result and
status: "AWAITING_CONFIRMATION".
Errors
400 VALIDATION_ERROR— missing required field, malformedflightDates, or non-positivebudget.total.403 FEATURE_NOT_ENABLED— directed mirror or the narrower directed-write alpha is not enabled for this customer.409 CONFLICT— a directed idempotency key was reused with a different payload, the expected revision is stale, or governance currency/caps reject the write.404 NOT_FOUND—advertiserIddoes not exist or is not visible to the authenticated account.
Related
Campaign tasks
All campaign operations
Campaign overview
Fields, lifecycle, and concepts
Auto-select products
Populate a campaign from decisioned inventory
Execute campaign
Launch into media buys