Skip to content

feat: Implement get_creative_delivery tool #1030

@bokelley

Description

@bokelley

Summary

Implement the get_creative_delivery AdCP v3 tool that provides creative-level and variant-level delivery metrics. This goes beyond get_media_buy_delivery by breaking down performance per creative and per rendered variant.

AdCP version: v3.0.0-beta.3 (adcp library 3.3.0)

What get_creative_delivery Does

Returns delivery metrics broken down by creative and variant. A "variant" is a specific rendered instance of a creative (e.g., different AI-generated versions for different contexts).

Request

class GetCreativeDeliveryRequest(AdCPBaseModel):
    media_buy_ids: list[str]               # Required: which media buys
    account_id: str | None                 # Account scoping
    creative_ids: list[str] | None         # Filter to specific creatives
    media_buy_buyer_refs: list[str] | None # Buyer reference IDs
    start_date: str | None                 # YYYY-MM-DD
    end_date: str | None                   # YYYY-MM-DD
    max_variants: int | None               # Limit variants per creative
    pagination: Pagination | None          # Offset-based (limit/offset)

Response Structure

GetCreativeDeliveryResponse
├── reporting_period (start, end, timezone)
├── currency
└── creatives[]
    ├── creative_id
    ├── format_id
    ├── media_buy_id
    ├── totals: DeliveryMetrics      # Aggregate for this creative
    ├── variant_count
    └── variants[]
        ├── variant_id
        ├── generation_context       # Where/how variant was rendered
        │   ├── context_type         # "web_page", "conversational", etc.
        │   └── artifact (property + artifact_id)
        ├── manifest                 # Rendered creative manifest
        └── DeliveryMetrics          # Variant-level metrics

DeliveryMetrics (comprehensive)

class DeliveryMetrics(AdCPBaseModel):
    impressions: float | None
    clicks: float | None
    ctr: float | None
    spend: float | None
    views: float | None
    completed_views: float | None
    completion_rate: float | None
    conversions: float | None
    conversion_value: float | None
    cost_per_acquisition: float | None
    cost_per_click: float | None
    roas: float | None
    reach: float | None
    frequency: float | None
    engagement_rate: float | None
    viewability: Viewability | None
    quartile_data: QuartileData | None
    by_event_type: list[ByEventTypeItem] | None
    by_action_source: list[ByActionSourceItem] | None

Implementation Plan

1. Add _impl() function

# src/core/tools/creative_delivery.py (new file)
from adcp.types import GetCreativeDeliveryRequest, GetCreativeDeliveryResponse

def _get_creative_delivery_impl(request, context) -> GetCreativeDeliveryResponse:
    # 1. Validate media_buy_ids belong to requesting agent/account
    # 2. Get creatives associated with those media buys
    # 3. Fetch delivery data per creative from adapter
    # 4. If variant tracking enabled, break down by variant
    # 5. Apply pagination and max_variants limits
    # 6. Return response

2. Adapter interface

# src/adapters/base.py
def get_creative_delivery(
    self, media_buy_ids: list[str], 
    creative_ids: list[str] | None,
    start_date: datetime | None,
    end_date: datetime | None,
) -> list[CreativeDeliveryData]:
    """Fetch creative-level delivery metrics from ad server."""

GAM adapter: Use Reporting API with CREATIVE_ID dimension + standard delivery metrics columns.

3. Variant Tracking

Variants are platform-specific. For GAM, different creative versions can be tracked via:

  • Custom creative templates with variant IDs
  • Creative set reporting
  • Line item creative associations

Initially, report at creative level (no variant breakdown) and add variant support as a follow-up.

Files to Create/Modify

File Change
src/core/tools/creative_delivery.py New: _get_creative_delivery_impl() + raw
src/core/main.py MCP tool wrapper
src/core/tools/__init__.py Export
src/adapters/base.py get_creative_delivery() interface
src/adapters/gam/managers/reporting.py Creative-level reporting
src/adapters/mock/adapter.py Mock implementation
tests/unit/test_creative_delivery.py Unit tests

Testing

uv run pytest tests/unit/test_creative_delivery.py -v

Test cases:

  • Returns creative-level metrics for valid media buy
  • Filters by creative_ids when provided
  • Pagination (offset/limit) works correctly
  • Date range filtering
  • Empty results for media buy with no creatives
  • Unauthorized media_buy_id returns error

Metadata

Metadata

Assignees

No one assigned

    Labels

    adcp-v3AdCP v3 spec gapenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions