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

# Create campaign

> Open a platform-managed campaign draft

`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. The legacy `routingType` field is not a
campaign input; it is derived per media buy as temporary billing compatibility
metadata from `BillingParty`. It is never a storefront or
execution type and is independent of campaign mode, BYOA, and protocol
connectivity. Execute the campaign later to turn it into live media buys.

Buyer-owned labels are applied through V3 MCP `save_campaign`, not this REST
create. See [Dimensions and labels](/v2/object-guides/dimension).

Every campaign budget is **GROSS**: `budget.total` is the all-in amount the buyer pays, with Apostra 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](/v2/concepts/budgets-and-fees)). There is no fee-model input at creation — the campaign object has no `feeType` field.

## Request

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://api.apostra.com/api/v2/buyer/campaigns \
    -H "Authorization: Bearer $SCOPE3_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "advertiserId": 12345,
      "name": "Q2 2026 Tech Launch",
      "flightDates": { "startDate": "2026-05-15T00:00:00Z", "endDate": "2026-07-15T23:59:59Z" },
      "budget": { "total": 100000, "currency": "USD", "pacing": "EVEN" },
      "brief": "Premium video for tech-savvy professionals",
      "constraints": {
        "channels": ["ctv", "video"],
        "geo_countries": ["US", "CA"],
        "geo_metros": [{ "system": "nielsen_dma", "values": ["501", "803"] }],
        "language": ["en"]
      }
    }'
  ```

  ```json With pacing periods theme={null}
  {
    "advertiserId": 12345,
    "name": "Holiday Heavy-Up",
    "flightDates": { "startDate": "2026-11-01T00:00:00Z", "endDate": "2026-12-31T23:59:59Z" },
    "budget": { "total": 250000, "currency": "USD" },
    "pacingPeriods": {
      "mode": "weight",
      "periods": [
        { "label": "Pre-Black Friday", "start": "2026-11-01T00:00:00Z", "end": "2026-11-26T23:59:59Z", "weight": 1.0 },
        { "label": "Black Friday / Cyber Monday", "start": "2026-11-27T00:00:00Z", "end": "2026-12-02T23:59:59Z", "weight": 3.0 },
        { "label": "Holiday push", "start": "2026-12-03T00:00:00Z", "end": "2026-12-31T23:59:59Z", "weight": 1.5 }
      ]
    }
  }
  ```
</CodeGroup>

## Parameters

| 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)                                                                                                                                                                                                                                                                             |

## Response

```json theme={null}
{
  "campaign": {
    "campaignId": "cmp_987654321",
    "advertiserId": "12345",
    "name": "Q2 2026 Tech Launch",
    "status": "DRAFT",
    "flightDates": { "startDate": "2026-05-15T00:00:00Z", "endDate": "2026-07-15T23:59:59Z" },
    "budget": { "total": 100000, "currency": "USD", "pacing": "EVEN" },
    "optimizationApplyMode": "MANUAL",
    "createdAt": "2026-05-01T09:00:00Z",
    "updatedAt": "2026-05-01T09:00:00Z"
  }
}
```

The campaign is created in `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.

## Errors

* `400 VALIDATION_ERROR` — missing required field, malformed `flightDates`, or non-positive `budget.total`.
* `404 NOT_FOUND` — `advertiserId` does not exist or is not visible to the authenticated account.

See [Errors](/v2/reference/errors) for the full error contract.

## Related

<CardGroup cols={2}>
  <Card title="Campaign tasks" href="/v2/buyer/campaigns/tasks" icon="list-check">
    All campaign operations
  </Card>

  <Card title="Campaign overview" href="/v2/object-guides/campaign" icon="rocket">
    Fields, lifecycle, and concepts
  </Card>

  <Card title="Auto-select products" href="/v2/buyer/campaigns/tasks/auto-select-products" icon="wand-magic-sparkles">
    Populate a campaign from eligible storefront inventory
  </Card>

  <Card title="Execute campaign" href="/v2/buyer/campaigns/tasks/execute-campaign" icon="rocket">
    Launch into media buys
  </Card>
</CardGroup>
