> ## Documentation Index
> Fetch the complete documentation index at: https://docs.adcontextprotocol.org/llms.txt
> Use this file to discover all available pages before exploring further.

# update_media_buy

> update_media_buy task — modify active AdCP campaigns with PATCH semantics. Update budgets, flight dates, targeting, status, and package-level settings.

Modify an existing media buy using PATCH semantics. Supports campaign-level and package-level updates.

**Response Time**: Instant to days (status: `completed`, `working` \< 120s, or `submitted` for manual review)

**PATCH Semantics**: Only specified fields are updated; omitted fields remain unchanged.

**Request Schema**: [`/schemas/v2/media-buy/update-media-buy-request.json`](https://adcontextprotocol.org/schemas/v2/media-buy/update-media-buy-request.json)
**Response Schema**: [`/schemas/v2/media-buy/update-media-buy-response.json`](https://adcontextprotocol.org/schemas/v2/media-buy/update-media-buy-response.json)

## Quick Start

Create a media buy, then pause it:

<CodeGroup>
  ```javascript JavaScript test=false theme={null}
  import { testAgent } from '@adcp/client/testing';
  import { CreateMediaBuyResponseSchema, UpdateMediaBuyResponseSchema } from '@adcp/client';

  // First, create a media buy to update
  const uniqueRef = `test_campaign_${Date.now()}`;

  // Use dates in the future
  const startDate = new Date();
  startDate.setDate(startDate.getDate() + 7); // Start 1 week from now
  const endDate = new Date();
  endDate.setDate(endDate.getDate() + 37); // End 5 weeks from now

  const createResult = await testAgent.createMediaBuy({
    buyer_ref: uniqueRef,
    brand: { domain: 'acmecorp.com' },
    packages: [{
      buyer_ref: 'display_pkg',
      product_id: 'prod_d979b543',
      pricing_option_id: 'cpm_usd_fixed',
      format_ids: [{
        agent_url: 'https://creative.adcontextprotocol.org',
        id: 'display_300x250_image'
      }],
      budget: 800,
      bid_price: 5.00
    }],
    start_time: startDate.toISOString(),
    end_time: endDate.toISOString()
  });

  if (!createResult.success) {
    throw new Error(`Create failed: ${createResult.error}`);
  }

  const created = CreateMediaBuyResponseSchema.parse(createResult.data);
  if ('errors' in created && created.errors) {
    throw new Error(`Create failed: ${JSON.stringify(created.errors)}`);
  }

  console.log(`Created media buy ${created.media_buy_id}`);

  // Now update it - pause the campaign
  const updateResult = await testAgent.updateMediaBuy({
    buyer_ref: uniqueRef,
    paused: true
  });

  if (!updateResult.success) {
    throw new Error(`Update failed: ${updateResult.error}`);
  }

  const updated = UpdateMediaBuyResponseSchema.parse(updateResult.data);
  if ('errors' in updated && updated.errors) {
    throw new Error(`Update failed: ${JSON.stringify(updated.errors)}`);
  }

  console.log(`Campaign ${updated.media_buy_id} paused`);
  ```

  ```python Python test=false theme={null}
  import asyncio
  import time
  from datetime import datetime, timedelta
  from adcp.testing import test_agent

  async def create_and_pause_campaign():
      # First, create a media buy to update
      unique_ref = f"test_campaign_{int(time.time() * 1000)}"

      # Use dates in the future
      start_date = datetime.utcnow() + timedelta(days=7)
      end_date = datetime.utcnow() + timedelta(days=37)

      create_result = await test_agent.simple.create_media_buy(
          buyer_ref=unique_ref,
          brand={'domain': 'acmecorp.com'},
          packages=[{
              'buyer_ref': 'display_pkg',
              'product_id': 'prod_d979b543',
              'pricing_option_id': 'cpm_usd_fixed',
              'format_ids': [{
                  'agent_url': 'https://creative.adcontextprotocol.org',
                  'id': 'display_300x250_image'
              }],
              'budget': 800,
              'bid_price': 5.00
          }],
          start_time=start_date.strftime('%Y-%m-%dT%H:%M:%SZ'),
          end_time=end_date.strftime('%Y-%m-%dT%H:%M:%SZ')
      )

      if hasattr(create_result, 'errors') and create_result.errors:
          raise Exception(f"Create failed: {create_result.errors}")

      print(f"Created media buy {create_result.media_buy_id}")

      # Now update it - pause the campaign
      update_result = await test_agent.simple.update_media_buy(
          buyer_ref=unique_ref,
          paused=True
      )

      if hasattr(update_result, 'errors') and update_result.errors:
          raise Exception(f"Update failed: {update_result.errors}")

      print(f"Campaign {update_result.media_buy_id} paused")

  asyncio.run(create_and_pause_campaign())
  ```
</CodeGroup>

## Request Parameters

| Parameter                  | Type             | Required | Description                                                       |
| -------------------------- | ---------------- | -------- | ----------------------------------------------------------------- |
| `media_buy_id`             | string           | Yes\*    | Publisher's media buy identifier to update                        |
| `buyer_ref`                | string           | Yes\*    | Your reference for the media buy to update                        |
| `start_time`               | string           | No       | Updated campaign start time                                       |
| `end_time`                 | string           | No       | Updated campaign end time                                         |
| `paused`                   | boolean          | No       | Pause/resume entire media buy (`true` = paused, `false` = active) |
| `packages`                 | PackageUpdate\[] | No       | Package-level updates (see below)                                 |
| `reporting_webhook`        | object           | No       | Update reporting webhook configuration (see below)                |
| `push_notification_config` | object           | No       | Webhook for async operation notifications                         |

\*Either `media_buy_id` OR `buyer_ref` is required (not both)

### Reporting Webhook Object

Configure automated delivery reporting for this media buy:

| Parameter             | Type      | Required | Description                                   |
| --------------------- | --------- | -------- | --------------------------------------------- |
| `url`                 | string    | Yes      | Webhook endpoint URL                          |
| `authentication`      | object    | Yes      | Auth config with `schemes` and `credentials`  |
| `reporting_frequency` | string    | Yes      | `hourly`, `daily`, or `monthly`               |
| `requested_metrics`   | string\[] | No       | Specific metrics to include (defaults to all) |
| `token`               | string    | No       | Client token for validation (min 16 chars)    |

**Note**: `reporting_webhook` configures ongoing campaign reporting. `push_notification_config` is for async operation notifications (e.g., "notify me when this update completes").

### Package Update Object

| Parameter                  | Type                  | Description                                                                                                                                                                                                              |
| -------------------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `package_id`               | string                | Publisher's package identifier to update                                                                                                                                                                                 |
| `buyer_ref`                | string                | Your reference for the package to update                                                                                                                                                                                 |
| `paused`                   | boolean               | Pause/resume specific package (`true` = paused, `false` = active)                                                                                                                                                        |
| `budget`                   | number                | Updated budget allocation                                                                                                                                                                                                |
| `impressions`              | number                | Updated impression goal for this package                                                                                                                                                                                 |
| `start_time`               | string                | Updated flight start date/time in ISO 8601 format. Must fall within the media buy's date range.                                                                                                                          |
| `end_time`                 | string                | Updated flight end date/time in ISO 8601 format. Must fall within the media buy's date range.                                                                                                                            |
| `pacing`                   | string                | Updated pacing strategy                                                                                                                                                                                                  |
| `bid_price`                | number                | Updated bid price (auction products only). This is the exact bid/price to honor unless the selected pricing option has `max_bid: true`, in which case it is treated as the buyer's maximum willingness to pay (ceiling). |
| `optimization_goals`       | OptimizationGoal\[]   | Replace all optimization goals for this package. Uses replacement semantics — omit to leave goals unchanged.                                                                                                             |
| `targeting_overlay`        | TargetingOverlay      | Updated targeting restrictions                                                                                                                                                                                           |
| `catalogs`                 | Catalog\[]            | Replace the catalogs this package promotes. Uses replacement semantics — omit to leave unchanged.                                                                                                                        |
| `keyword_targets_add`      | KeywordTarget\[]      | Keyword targets to add or upsert by (keyword, match\_type) identity. On create, these are set as `keyword_targets` inside `targeting_overlay`.                                                                           |
| `keyword_targets_remove`   | KeywordTarget\[]      | Keyword targets to remove by (keyword, match\_type) identity.                                                                                                                                                            |
| `negative_keywords_add`    | NegativeKeyword\[]    | Negative keywords to append to this package. On create, these are set as `negative_keywords` inside `targeting_overlay`.                                                                                                 |
| `negative_keywords_remove` | NegativeKeyword\[]    | Negative keywords to remove from this package.                                                                                                                                                                           |
| `creative_assignments`     | CreativeAssignment\[] | Replace assigned creatives with optional weights and placement targeting                                                                                                                                                 |
| `creatives`                | CreativeAsset\[]      | Upload and assign new creatives inline (must not exist in library)                                                                                                                                                       |

\*Either `package_id` OR `buyer_ref` is required for each package update

## Response

### Success Response

| Field                 | Description                                                            |
| --------------------- | ---------------------------------------------------------------------- |
| `media_buy_id`        | Media buy identifier                                                   |
| `buyer_ref`           | Your reference identifier                                              |
| `implementation_date` | ISO 8601 timestamp when changes take effect (null if pending approval) |
| `affected_packages`   | Array of full Package objects showing complete state after update      |

### Error Response

| Field    | Description                               |
| -------- | ----------------------------------------- |
| `errors` | Array of error objects explaining failure |

**Note**: Responses use discriminated unions - you get either success fields OR errors, never both. Always check for `errors` before accessing success fields.

## Common Scenarios

### Update Package Budget

Increase budget for a specific package:

<CodeGroup>
  ```javascript test=false JavaScript theme={null}
  import { testAgent } from '@adcp/client/testing';
  import { UpdateMediaBuyResponseSchema } from '@adcp/client';

  const result = await testAgent.updateMediaBuy({
    media_buy_id: 'mb_12345',
    packages: [{
      buyer_ref: 'ctv_package',
      budget: 50000  // Increased from 30000
    }]
  });

  if (!result.success) {
    throw new Error(`Request failed: ${result.error}`);
  }

  const validated = UpdateMediaBuyResponseSchema.parse(result.data);

  if ('errors' in validated && validated.errors) {
    throw new Error(`Update failed: ${JSON.stringify(validated.errors)}`);
  }

  const pkg = validated.affected_packages?.find(p => p.buyer_ref === 'ctv_package');
  if (pkg) {
    console.log(`Package budget updated to ${pkg.budget}`);
  }
  ```

  ```python test=false Python theme={null}
  import asyncio
  from adcp.testing import test_agent
  from adcp.types import UpdateMediaBuyRequest

  async def increase_budget():
      result = await test_agent.update_media_buy(
          UpdateMediaBuyRequest(
              media_buy_id='mb_12345',
              packages=[
                  {'buyer_ref': 'ctv_package', 'budget': 50000}
              ]
          )
      )

      if hasattr(result, 'errors') and result.errors:
          raise Exception(f"Update failed: {result.errors}")

      pkg = next((p for p in result.affected_packages if p.buyer_ref == 'ctv_package'), None)
      if pkg:
          print(f"Package budget updated to {pkg.budget}")

  asyncio.run(increase_budget())
  ```
</CodeGroup>

### Change Campaign Dates

Extend campaign end date:

<CodeGroup>
  ```javascript test=false JavaScript theme={null}
  import { testAgent } from '@adcp/client/testing';
  import { UpdateMediaBuyResponseSchema } from '@adcp/client';

  const result = await testAgent.updateMediaBuy({
    buyer_ref: 'summer_campaign_2025',
    end_time: '2025-09-30T23:59:59Z'
  });

  if (!result.success) {
    throw new Error(`Request failed: ${result.error}`);
  }

  const validated = UpdateMediaBuyResponseSchema.parse(result.data);

  if ('errors' in validated && validated.errors) {
    throw new Error(`Update failed: ${JSON.stringify(validated.errors)}`);
  }

  console.log('Campaign end date extended');
  console.log(`Effective: ${validated.implementation_date}`);
  ```

  ```python test=false Python theme={null}
  import asyncio
  from adcp.testing import test_agent
  from adcp.types import UpdateMediaBuyRequest

  async def extend_campaign():
      result = await test_agent.update_media_buy(
          UpdateMediaBuyRequest(
              buyer_ref='summer_campaign_2025',
              end_time='2025-09-30T23:59:59Z'
          )
      )

      if hasattr(result, 'errors') and result.errors:
          raise Exception(f"Update failed: {result.errors}")

      print('Campaign end date extended')
      print(f"Effective: {result.implementation_date}")

  asyncio.run(extend_campaign())
  ```
</CodeGroup>

### Update Targeting

Add or modify geographic restrictions:

<CodeGroup>
  ```javascript test=false JavaScript theme={null}
  import { testAgent } from '@adcp/client/testing';
  import { UpdateMediaBuyResponseSchema } from '@adcp/client';

  const result = await testAgent.updateMediaBuy({
    media_buy_id: 'mb_12345',
    packages: [{
      buyer_ref: 'ctv_package',
      targeting_overlay: {
        geo_countries: ['US', 'CA'],
        geo_regions: ['US-CA', 'US-NY', 'US-TX', 'CA-ON', 'CA-QC']
      }
    }]
  });

  if (!result.success) {
    throw new Error(`Request failed: ${result.error}`);
  }

  const validated = UpdateMediaBuyResponseSchema.parse(result.data);

  if ('errors' in validated && validated.errors) {
    throw new Error(`Update failed: ${JSON.stringify(validated.errors)}`);
  }

  console.log('Targeting updated successfully');
  ```

  ```python test=false Python theme={null}
  import asyncio
  from adcp.testing import test_agent
  from adcp.types import UpdateMediaBuyRequest

  async def update_targeting():
      result = await test_agent.update_media_buy(
          UpdateMediaBuyRequest(
              media_buy_id='mb_12345',
              packages=[
                  {
                      'buyer_ref': 'ctv_package',
                      'targeting_overlay': {
                          'geo_countries': ['US', 'CA'],
                          'geo_regions': ['US-CA', 'US-NY', 'US-TX', 'CA-ON', 'CA-QC']
                      }
                  }
              ]
          )
      )

      if hasattr(result, 'errors') and result.errors:
          raise Exception(f"Update failed: {result.errors}")

      print('Targeting updated successfully')

  asyncio.run(update_targeting())
  ```
</CodeGroup>

### Replace Creatives

Swap out creative assignments for a package:

<CodeGroup>
  ```javascript test=false JavaScript theme={null}
  import { testAgent } from '@adcp/client/testing';
  import { UpdateMediaBuyResponseSchema } from '@adcp/client';

  const result = await testAgent.updateMediaBuy({
    media_buy_id: 'mb_12345',
    packages: [{
      buyer_ref: 'ctv_package',
      creative_assignments: [
        { creative_id: 'creative_video_v2' },
        { creative_id: 'creative_display_v2', weight: 60 }
      ]
    }]
  });

  if (!result.success) {
    throw new Error(`Request failed: ${result.error}`);
  }

  const validated = UpdateMediaBuyResponseSchema.parse(result.data);

  if ('errors' in validated && validated.errors) {
    throw new Error(`Update failed: ${JSON.stringify(validated.errors)}`);
  }

  const pkg = validated.affected_packages?.find(p => p.buyer_ref === 'ctv_package');
  const assignmentCount = pkg?.creative_assignments?.length || 0;
  console.log(`Assigned ${assignmentCount} creatives`);
  ```

  ```python test=false Python theme={null}
  import asyncio
  from adcp.testing import test_agent
  from adcp.types import UpdateMediaBuyRequest

  async def replace_creatives():
      result = await test_agent.update_media_buy(
          UpdateMediaBuyRequest(
              media_buy_id='mb_12345',
              packages=[
                  {
                      'buyer_ref': 'ctv_package',
                      'creative_assignments': [
                          {'creative_id': 'creative_video_v2'},
                          {'creative_id': 'creative_display_v2', 'weight': 60}
                      ]
                  }
              ]
          )
      )

      if hasattr(result, 'errors') and result.errors:
          raise Exception(f"Update failed: {result.errors}")

      pkg = next((p for p in result.affected_packages if p.buyer_ref == 'ctv_package'), None)
      assignment_count = len(pkg.creative_assignments) if pkg and pkg.creative_assignments else 0
      print(f"Assigned {assignment_count} creatives")

  asyncio.run(replace_creatives())
  ```
</CodeGroup>

### Multiple Package Updates

Update multiple packages in one call:

<CodeGroup>
  ```javascript test=false JavaScript theme={null}
  import { testAgent } from '@adcp/client/testing';
  import { UpdateMediaBuyResponseSchema } from '@adcp/client';

  const result = await testAgent.updateMediaBuy({
    media_buy_id: 'mb_12345',
    packages: [
      {
        buyer_ref: 'ctv_package',
        budget: 50000,
        pacing: 'front_loaded'
      },
      {
        buyer_ref: 'audio_package',
        budget: 30000,
        paused: true
      }
    ]
  });

  if (!result.success) {
    throw new Error(`Request failed: ${result.error}`);
  }

  const validated = UpdateMediaBuyResponseSchema.parse(result.data);

  if ('errors' in validated && validated.errors) {
    throw new Error(`Update failed: ${JSON.stringify(validated.errors)}`);
  }

  console.log(`Updated ${validated.affected_packages?.length || 0} packages`);
  ```

  ```python test=false Python theme={null}
  import asyncio
  from adcp.testing import test_agent
  from adcp.types import UpdateMediaBuyRequest

  async def update_multiple_packages():
      result = await test_agent.update_media_buy(
          UpdateMediaBuyRequest(
              media_buy_id='mb_12345',
              packages=[
                  {
                      'buyer_ref': 'ctv_package',
                      'budget': 50000,
                      'pacing': 'front_loaded'
                  },
                  {
                      'buyer_ref': 'audio_package',
                      'budget': 30000,
                      'paused': True
                  }
              ]
          )
      )

      if hasattr(result, 'errors') and result.errors:
          raise Exception(f"Update failed: {result.errors}")

      print(f"Updated {len(result.affected_packages)} packages")

  asyncio.run(update_multiple_packages())
  ```
</CodeGroup>

## What Can Be Updated

### Campaign-Level Updates

✅ **Can update:**

* Start/end times (subject to seller approval)
* Campaign status (active/paused)
* Reporting webhook configuration (URL, frequency, metrics)

❌ **Cannot update:**

* Media buy ID
* Buyer reference
* Brand reference
* Original package product IDs

### Package-Level Updates

✅ **Can update:**

* Budget allocation
* Pacing strategy
* Bid prices (auction products)
* Optimization goal (event source, event type, target ROAS/CPA)
* Targeting overlays
* Creative assignments
* Package status (active/paused)
* Catalog reference (replace the catalog a catalog-driven package promotes)

❌ **Cannot update:**

* Package ID
* Product ID
* Pricing option ID
* Format IDs (creatives must match existing formats)

## Error Handling

Common errors and resolutions:

| Error Code            | Description                            | Resolution                                                                                                          |
| --------------------- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `MEDIA_BUY_NOT_FOUND` | Media buy doesn't exist                | Verify media\_buy\_id or buyer\_ref                                                                                 |
| `PACKAGE_NOT_FOUND`   | Package doesn't exist                  | Verify package\_id or buyer\_ref                                                                                    |
| `UPDATE_NOT_ALLOWED`  | Field cannot be changed                | See "What Can Be Updated" above                                                                                     |
| `BUDGET_INSUFFICIENT` | New budget below minimum               | Increase budget amount                                                                                              |
| `POLICY_VIOLATION`    | Update violates content policy         | Review policy requirements                                                                                          |
| `INVALID_STATE`       | Operation not allowed in current state | Check campaign status                                                                                               |
| `CREATIVE_ID_EXISTS`  | Creative ID already exists in library  | Use a different `creative_id`, assign existing creatives via `creative_assignments`, or update via `sync_creatives` |

Example error response:

```json theme={null}
{
  "errors": [{
    "code": "UPDATE_NOT_ALLOWED",
    "message": "Cannot change product_id for existing package",
    "field": "packages[0].product_id",
    "suggestion": "Create a new package with the desired product instead"
  }]
}
```

## Update Approval

Some updates require seller approval and return pending status:

* **Significant budget increases** (threshold varies by seller)
* **Date range changes** affecting inventory availability
* **Targeting changes** that alter campaign scope
* **Creative changes** requiring policy review

When approval is needed, `implementation_date` will be `null` and `affected_packages` contains the proposed state of each package that would be modified:

```json theme={null}
{
  "media_buy_id": "mb_12345",
  "buyer_ref": "summer_campaign_2025",
  "implementation_date": null,
  "affected_packages": [
    {
      "package_id": "pkg_abc123",
      "buyer_ref": "ctv_package",
      "budget": 50000,
      "status": "pending_activation"
    }
  ]
}
```

## PATCH Semantics

Only specified fields are updated - omitted fields remain unchanged:

```json theme={null}
{
  "buyer_ref": "summer_campaign_2025",
  "packages": [{
    "buyer_ref": "ctv_package",
    "budget": 50000
  }]
}
```

**Array replacement**: When updating arrays (like `creative_assignments`), provide the complete new array:

```json theme={null}
{
  "packages": [{
    "buyer_ref": "ctv_package",
    "creative_assignments": [
      { "creative_id": "creative_video_v2" },
      { "creative_id": "creative_display_v2", "weight": 60 }
    ]
  }]
}
```

## Asynchronous Operations

Updates may be asynchronous, especially with seller approval.

### Response Patterns

**Synchronous (completed immediately)** — campaign-level update (e.g., `paused: true`):

```json theme={null}
{
  "media_buy_id": "mb_12345",
  "buyer_ref": "summer_campaign_2025",
  "implementation_date": "2025-06-15T10:00:00Z",
  "affected_packages": []
}
```

**Synchronous (completed immediately)** — package-level update:

```json theme={null}
{
  "media_buy_id": "mb_12345",
  "buyer_ref": "summer_campaign_2025",
  "implementation_date": "2025-06-15T10:00:00Z",
  "affected_packages": [
    {
      "package_id": "pkg_abc123",
      "buyer_ref": "ctv_package",
      "budget": 50000,
      "status": "active"
    }
  ]
}
```

**Asynchronous (processing)**:

```json theme={null}
{
  "status": "working",
  "message": "Processing update..."
}
```

Poll for completion or use webhooks/streaming.

**Manual Approval Required**:

```json theme={null}
{
  "status": "submitted",
  "message": "Update requires seller approval (2-4 hours)"
}
```

Will take hours to days.

### Protocol-Specific Handling

AdCP tasks work across multiple protocols (MCP, A2A, REST). Each protocol handles async operations differently:

* **Status checking**: Polling, webhooks, or streaming
* **Updates**: Protocol-specific mechanisms
* **Long-running tasks**: Different timeout and notification patterns

See [Async Operations](/dist/docs/3.0.0-rc.2/building/implementation/async-operations) for protocol-specific async patterns and examples.

## Best Practices

**1. Use Precise Updates**
Update only what needs to change - don't resend unchanged values.

**2. Budget Increases**
Small incremental increases are more likely to be auto-approved than large jumps.

**3. Pause Before Major Changes**
Pause campaigns before making significant targeting or creative changes to avoid delivery issues.

**4. Test with Small Changes**
Test update workflows with minor changes before critical campaign modifications.

**5. Monitor Status**
Always check response status and `implementation_date` for approval requirements.

**6. Validate Package State**
Check `affected_packages` in response to confirm changes were applied correctly.

## Usage Notes

* Updates are atomic - either all changes apply or none do
* Both media buys and packages can be referenced by `buyer_ref` or publisher IDs
* Pending states (`working`, `submitted`) are normal, not errors
* Orchestrators MUST handle pending states as part of normal workflow
* `implementation_date` indicates when changes take effect (null if pending approval)
* **Inline creatives**: The `creatives` array creates NEW creatives only. To update existing creatives, use [`sync_creatives`](/dist/docs/3.0.0-rc.2/creative/task-reference/sync_creatives). To assign existing library creatives, use `creative_assignments` in the Package Update object.

## Next Steps

After updating a media buy:

1. **Verify Changes**: Use [`get_media_buy_delivery`](/dist/docs/3.0.0-rc.2/media-buy/task-reference/get_media_buy_delivery) to confirm updates
2. **Upload New Creatives**: Use [`sync_creatives`](/dist/docs/3.0.0-rc.2/creative/task-reference/sync_creatives) if creative assignments changed
3. **Monitor Performance**: Track impact of changes on campaign metrics
4. **Optimize Further**: Use [`provide_performance_feedback`](/dist/docs/3.0.0-rc.2/media-buy/task-reference/provide_performance_feedback) for ongoing optimization

## Learn More

* [Media Buy Lifecycle](/dist/docs/3.0.0-rc.2/media-buy/media-buys/) - Complete campaign workflow
* [Targeting](/dist/docs/3.0.0-rc.2/media-buy/advanced-topics/targeting) - Targeting overlays and restrictions
* [Async Operations](/dist/docs/3.0.0-rc.2/building/implementation/async-operations) - Async patterns and status checking
* [create\_media\_buy](/dist/docs/3.0.0-rc.2/media-buy/task-reference/create_media_buy) - Initial campaign creation
