Package adcp
Sub-modules
adcp.adagentsadcp.clientadcp.configadcp.exceptionsadcp.protocolsadcp.simple-
Simplified API accessor for ADCPClient …
adcp.testing-
Test helpers for AdCP client library …
adcp.typesadcp.utilsadcp.validation-
Runtime validation for AdCP data structures …
Functions
def create_test_agent(**overrides: Any) ‑> AgentConfig-
Expand source code
def create_test_agent(**overrides: Any) -> AgentConfig: """Create a custom test agent configuration. Useful when you need to modify the default test agent setup. Args: **overrides: Keyword arguments to override default config values Returns: Complete agent configuration Example: ```python from adcp.testing import create_test_agent from adcp.client import ADCPClient # Use default test agent with custom ID config = create_test_agent(id="my-test-agent") client = ADCPClient(config) ``` Example: ```python # Use A2A protocol instead of MCP from adcp.types.core import Protocol config = create_test_agent( protocol=Protocol.A2A, agent_uri="https://test-agent.adcontextprotocol.org" ) ``` """ base_config = TEST_AGENT_MCP_CONFIG.model_dump() base_config.update(overrides) return AgentConfig(**base_config)Create a custom test agent configuration.
Useful when you need to modify the default test agent setup.
Args
**overrides- Keyword arguments to override default config values
Returns
Complete agent configuration
Example
from adcp.testing import create_test_agent from adcp.client import ADCPClient # Use default test agent with custom ID config = create_test_agent(id="my-test-agent") client = ADCPClient(config)Example
# Use A2A protocol instead of MCP from adcp.types.core import Protocol config = create_test_agent( protocol=Protocol.A2A, agent_uri="https://test-agent.adcontextprotocol.org" ) def domain_matches(property_domain: str, agent_domain_pattern: str) ‑> bool-
Expand source code
def domain_matches(property_domain: str, agent_domain_pattern: str) -> bool: """Check if domains match per AdCP rules. Rules: - Exact match always succeeds - 'example.com' matches www.example.com, m.example.com (common subdomains) - 'subdomain.example.com' matches that specific subdomain only - '*.example.com' matches all subdomains Args: property_domain: Domain from property agent_domain_pattern: Domain pattern from adagents.json Returns: True if domains match per AdCP rules """ # Normalize both domains for comparison try: property_domain = _normalize_domain(property_domain) agent_domain_pattern = _normalize_domain(agent_domain_pattern) except AdagentsValidationError: # Invalid domain format - no match return False # Exact match if property_domain == agent_domain_pattern: return True # Wildcard pattern (*.example.com) if agent_domain_pattern.startswith("*."): base_domain = agent_domain_pattern[2:] return property_domain.endswith(f".{base_domain}") # Bare domain matches common subdomains (www, m) # If agent pattern is a bare domain (no subdomain), match www/m subdomains if "." in agent_domain_pattern and not agent_domain_pattern.startswith("www."): # Check if this looks like a bare domain (e.g., example.com) parts = agent_domain_pattern.split(".") if len(parts) == 2: # Looks like bare domain common_subdomains = ["www", "m"] for subdomain in common_subdomains: if property_domain == f"{subdomain}.{agent_domain_pattern}": return True return FalseCheck if domains match per AdCP rules.
Rules: - Exact match always succeeds - 'example.com' matches www.example.com, m.example.com (common subdomains) - 'subdomain.example.com' matches that specific subdomain only - '*.example.com' matches all subdomains
Args
property_domain- Domain from property
agent_domain_pattern- Domain pattern from adagents.json
Returns
True if domains match per AdCP rules
async def fetch_adagents(publisher_domain: str,
timeout: float = 10.0,
user_agent: str = 'AdCP-Client/1.0',
client: httpx.AsyncClient | None = None) ‑> dict[str, typing.Any]-
Expand source code
async def fetch_adagents( publisher_domain: str, timeout: float = 10.0, user_agent: str = "AdCP-Client/1.0", client: httpx.AsyncClient | None = None, ) -> dict[str, Any]: """Fetch and parse adagents.json from publisher domain. Args: publisher_domain: Domain hosting the adagents.json file timeout: Request timeout in seconds user_agent: User-Agent header for HTTP request client: Optional httpx.AsyncClient for connection pooling. If provided, caller is responsible for client lifecycle. If None, a new client is created for this request. Returns: Parsed adagents.json data Raises: AdagentsNotFoundError: If adagents.json not found (404) AdagentsValidationError: If JSON is invalid or malformed AdagentsTimeoutError: If request times out Notes: For production use with multiple requests, pass a shared httpx.AsyncClient to enable connection pooling and improve performance. """ # Validate and normalize domain for security publisher_domain = _validate_publisher_domain(publisher_domain) # Construct URL url = f"https://{publisher_domain}/.well-known/adagents.json" try: # Use provided client or create a new one if client is not None: # Reuse provided client (connection pooling) response = await client.get( url, headers={"User-Agent": user_agent}, timeout=timeout, follow_redirects=True, ) else: # Create new client for single request async with httpx.AsyncClient() as new_client: response = await new_client.get( url, headers={"User-Agent": user_agent}, timeout=timeout, follow_redirects=True, ) # Process response (same for both paths) if response.status_code == 404: raise AdagentsNotFoundError(publisher_domain) if response.status_code != 200: raise AdagentsValidationError( f"Failed to fetch adagents.json: HTTP {response.status_code}" ) # Parse JSON try: data = response.json() except Exception as e: raise AdagentsValidationError(f"Invalid JSON in adagents.json: {e}") from e # Validate basic structure if not isinstance(data, dict): raise AdagentsValidationError("adagents.json must be a JSON object") if "authorized_agents" not in data: raise AdagentsValidationError("adagents.json must have 'authorized_agents' field") if not isinstance(data["authorized_agents"], list): raise AdagentsValidationError("'authorized_agents' must be an array") # Validate mutual exclusivity constraints try: validate_adagents(data) except ValidationError as e: raise AdagentsValidationError(f"Invalid adagents.json structure: {e}") from e return data except httpx.TimeoutException as e: raise AdagentsTimeoutError(publisher_domain, timeout) from e except httpx.RequestError as e: raise AdagentsValidationError(f"Failed to fetch adagents.json: {e}") from eFetch and parse adagents.json from publisher domain.
Args
publisher_domain- Domain hosting the adagents.json file
timeout- Request timeout in seconds
user_agent- User-Agent header for HTTP request
client- Optional httpx.AsyncClient for connection pooling. If provided, caller is responsible for client lifecycle. If None, a new client is created for this request.
Returns
Parsed adagents.json data
Raises
AdagentsNotFoundError- If adagents.json not found (404)
AdagentsValidationError- If JSON is invalid or malformed
AdagentsTimeoutError- If request times out
Notes
For production use with multiple requests, pass a shared httpx.AsyncClient to enable connection pooling and improve performance.
-
Expand source code
async def fetch_agent_authorizations( agent_url: str, publisher_domains: list[str], timeout: float = 10.0, client: httpx.AsyncClient | None = None, ) -> dict[str, AuthorizationContext]: """Fetch authorization contexts by checking publisher adagents.json files. This function discovers what publishers have authorized your agent by fetching their adagents.json files from the .well-known directory and extracting the properties your agent can access. This is the "pull" approach - you query publishers to see if they've authorized you. For the "push" approach where the agent tells you what it's authorized for, use the agent's list_authorized_properties endpoint via ADCPClient. Args: agent_url: URL of your sales agent publisher_domains: List of publisher domains to check (e.g., ["nytimes.com", "wsj.com"]) timeout: Request timeout in seconds for each fetch client: Optional httpx.AsyncClient for connection pooling Returns: Dictionary mapping publisher domain to AuthorizationContext. Only includes domains where the agent is authorized. Example: >>> # "Pull" approach - check what publishers have authorized you >>> contexts = await fetch_agent_authorizations( ... "https://our-sales-agent.com", ... ["nytimes.com", "wsj.com", "cnn.com"] ... ) >>> for domain, ctx in contexts.items(): ... print(f"{domain}:") ... print(f" Property IDs: {ctx.property_ids}") ... print(f" Tags: {ctx.property_tags}") See Also: ADCPClient.list_authorized_properties: "Push" approach using the agent's API Notes: - Silently skips domains where adagents.json is not found or invalid - Only returns domains where the agent is explicitly authorized - For production use with many domains, pass a shared httpx.AsyncClient to enable connection pooling """ import asyncio # Create tasks to fetch all adagents.json files in parallel async def fetch_authorization_for_domain( domain: str, ) -> tuple[str, AuthorizationContext | None]: """Fetch authorization context for a single domain.""" try: adagents_data = await fetch_adagents(domain, timeout=timeout, client=client) # Check if agent is authorized if not verify_agent_authorization(adagents_data, agent_url): return (domain, None) # Get properties for this agent properties = get_properties_by_agent(adagents_data, agent_url) # Create authorization context return (domain, AuthorizationContext(properties)) except (AdagentsNotFoundError, AdagentsValidationError, AdagentsTimeoutError): # Silently skip domains with missing or invalid adagents.json return (domain, None) # Fetch all domains in parallel tasks = [fetch_authorization_for_domain(domain) for domain in publisher_domains] results = await asyncio.gather(*tasks) # Build result dictionary, filtering out None values return {domain: ctx for domain, ctx in results if ctx is not None}Fetch authorization contexts by checking publisher adagents.json files.
This function discovers what publishers have authorized your agent by fetching their adagents.json files from the .well-known directory and extracting the properties your agent can access.
This is the "pull" approach - you query publishers to see if they've authorized you. For the "push" approach where the agent tells you what it's authorized for, use the agent's list_authorized_properties endpoint via ADCPClient.
Args
agent_url- URL of your sales agent
publisher_domains- List of publisher domains to check (e.g., ["nytimes.com", "wsj.com"])
timeout- Request timeout in seconds for each fetch
client- Optional httpx.AsyncClient for connection pooling
Returns
Dictionary mapping publisher domain to AuthorizationContext. Only includes domains where the agent is authorized.
Example
>>> # "Pull" approach - check what publishers have authorized you >>> contexts = await fetch_agent_authorizations( ... "https://our-sales-agent.com", ... ["nytimes.com", "wsj.com", "cnn.com"] ... ) >>> for domain, ctx in contexts.items(): ... print(f"{domain}:") ... print(f" Property IDs: {ctx.property_ids}") ... print(f" Tags: {ctx.property_tags}")See Also: ADCPClient.list_authorized_properties: "Push" approach using the agent's API
Notes
- Silently skips domains where adagents.json is not found or invalid
- Only returns domains where the agent is explicitly authorized
- For production use with many domains, pass a shared httpx.AsyncClient to enable connection pooling
def get_all_properties(adagents_data: dict[str, Any]) ‑> list[dict[str, typing.Any]]-
Expand source code
def get_all_properties(adagents_data: dict[str, Any]) -> list[dict[str, Any]]: """Extract all properties from adagents.json data. Args: adagents_data: Parsed adagents.json data Returns: List of all properties across all authorized agents, with agent_url added Raises: AdagentsValidationError: If adagents_data is malformed """ if not isinstance(adagents_data, dict): raise AdagentsValidationError("adagents_data must be a dictionary") authorized_agents = adagents_data.get("authorized_agents") if not isinstance(authorized_agents, list): raise AdagentsValidationError("adagents.json must have 'authorized_agents' array") properties = [] for agent in authorized_agents: if not isinstance(agent, dict): continue agent_url = agent.get("url", "") if not agent_url: continue agent_properties = agent.get("properties", []) if not isinstance(agent_properties, list): continue # Add each property with the agent URL for reference for prop in agent_properties: if isinstance(prop, dict): # Create a copy and add agent_url prop_with_agent = {**prop, "agent_url": agent_url} properties.append(prop_with_agent) return propertiesExtract all properties from adagents.json data.
Args
adagents_data- Parsed adagents.json data
Returns
List of all properties across all authorized agents, with agent_url added
Raises
AdagentsValidationError- If adagents_data is malformed
-
Expand source code
def get_all_tags(adagents_data: dict[str, Any]) -> set[str]: """Extract all unique tags from properties in adagents.json data. Args: adagents_data: Parsed adagents.json data Returns: Set of all unique tags across all properties Raises: AdagentsValidationError: If adagents_data is malformed """ properties = get_all_properties(adagents_data) tags = set() for prop in properties: prop_tags = prop.get("tags", []) if isinstance(prop_tags, list): for tag in prop_tags: if isinstance(tag, str): tags.add(tag) return tagsExtract all unique tags from properties in adagents.json data.
Args
adagents_data- Parsed adagents.json data
Returns
Set of all unique tags across all properties
Raises
AdagentsValidationError- If adagents_data is malformed
def get_properties_by_agent(adagents_data: dict[str, Any], agent_url: str) ‑> list[dict[str, typing.Any]]-
Expand source code
def get_properties_by_agent(adagents_data: dict[str, Any], agent_url: str) -> list[dict[str, Any]]: """Get all properties authorized for a specific agent. Args: adagents_data: Parsed adagents.json data agent_url: URL of the agent to filter by Returns: List of properties for the specified agent (empty if agent not found or no properties) Raises: AdagentsValidationError: If adagents_data is malformed """ if not isinstance(adagents_data, dict): raise AdagentsValidationError("adagents_data must be a dictionary") authorized_agents = adagents_data.get("authorized_agents") if not isinstance(authorized_agents, list): raise AdagentsValidationError("adagents.json must have 'authorized_agents' array") # Normalize the agent URL for comparison normalized_agent_url = normalize_url(agent_url) for agent in authorized_agents: if not isinstance(agent, dict): continue agent_url_from_json = agent.get("url", "") if not agent_url_from_json: continue # Match agent URL (protocol-agnostic) if normalize_url(agent_url_from_json) != normalized_agent_url: continue # Found the agent - return their properties properties = agent.get("properties", []) if not isinstance(properties, list): return [] return [p for p in properties if isinstance(p, dict)] return []Get all properties authorized for a specific agent.
Args
adagents_data- Parsed adagents.json data
agent_url- URL of the agent to filter by
Returns
List of properties for the specified agent (empty if agent not found or no properties)
Raises
AdagentsValidationError- If adagents_data is malformed
def identifiers_match(property_identifiers: list[dict[str, str]],
agent_identifiers: list[dict[str, str]]) ‑> bool-
Expand source code
def identifiers_match( property_identifiers: list[dict[str, str]], agent_identifiers: list[dict[str, str]], ) -> bool: """Check if any property identifier matches agent's authorized identifiers. Args: property_identifiers: Identifiers from property (e.g., [{"type": "domain", "value": "cnn.com"}]) agent_identifiers: Identifiers from adagents.json Returns: True if any identifier matches Notes: - Domain identifiers use AdCP domain matching rules - Other identifiers (bundle_id, roku_store_id, etc.) require exact match """ for prop_id in property_identifiers: prop_type = prop_id.get("type", "") prop_value = prop_id.get("value", "") for agent_id in agent_identifiers: agent_type = agent_id.get("type", "") agent_value = agent_id.get("value", "") # Type must match if prop_type != agent_type: continue # Domain identifiers use special matching rules if prop_type == "domain": if domain_matches(prop_value, agent_value): return True else: # Other identifier types require exact match if prop_value == agent_value: return True return FalseCheck if any property identifier matches agent's authorized identifiers.
Args
property_identifiers- Identifiers from property (e.g., [{"type": "domain", "value": "cnn.com"}])
agent_identifiers- Identifiers from adagents.json
Returns
True if any identifier matches
Notes
- Domain identifiers use AdCP domain matching rules
- Other identifiers (bundle_id, roku_store_id, etc.) require exact match
def validate_adagents(adagents: dict[str, Any]) ‑> None-
Expand source code
def validate_adagents(adagents: dict[str, Any]) -> None: """Validate an adagents.json structure. Args: adagents: The adagents.json dict Raises: ValidationError: If validation fails """ if "agents" in adagents: for agent in adagents["agents"]: validate_agent_authorization(agent)Validate an adagents.json structure.
Args
adagents- The adagents.json dict
Raises
ValidationError- If validation fails
-
Expand source code
def validate_agent_authorization(agent: dict[str, Any]) -> None: """Validate agent authorization discriminated union. AdCP v2.4.0+ uses discriminated unions with authorization_type discriminator: - authorization_type: "property_ids" requires property_ids - authorization_type: "property_tags" requires property_tags - authorization_type: "inline_properties" requires properties - authorization_type: "publisher_properties" requires publisher_properties For backward compatibility, also validates the old mutual exclusivity constraint. Args: agent: An agent dict from adagents.json Raises: ValidationError: If discriminator or field constraints are violated """ authorization_type = agent.get("authorization_type") auth_fields = ["properties", "property_ids", "property_tags", "publisher_properties"] present_fields = [field for field in auth_fields if field in agent and agent[field] is not None] # If authorization_type discriminator is present, validate discriminated union if authorization_type: if authorization_type == "property_ids" and "property_ids" not in present_fields: raise ValidationError( "Agent with authorization_type='property_ids' must have property_ids" ) elif authorization_type == "property_tags" and "property_tags" not in present_fields: raise ValidationError( "Agent with authorization_type='property_tags' must have property_tags" ) elif authorization_type == "inline_properties" and "properties" not in present_fields: raise ValidationError( "Agent with authorization_type='inline_properties' must have properties" ) elif ( authorization_type == "publisher_properties" and "publisher_properties" not in present_fields ): raise ValidationError( "Agent with authorization_type='publisher_properties' " "must have publisher_properties" ) elif authorization_type not in ( "property_ids", "property_tags", "inline_properties", "publisher_properties", ): raise ValidationError(f"Agent has invalid authorization_type: {authorization_type}") # Validate mutual exclusivity (for both old and new formats) if len(present_fields) > 1: raise ValidationError( f"Agent authorization cannot have multiple fields: {', '.join(present_fields)}. " f"Only one of {', '.join(auth_fields)} is allowed." ) if len(present_fields) == 0: raise ValidationError( f"Agent authorization must have exactly one of: {', '.join(auth_fields)}." ) # If using publisher_properties, validate each item if "publisher_properties" in present_fields: for pub_prop in agent["publisher_properties"]: validate_publisher_properties_item(pub_prop)Validate agent authorization discriminated union.
AdCP v2.4.0+ uses discriminated unions with authorization_type discriminator: - authorization_type: "property_ids" requires property_ids - authorization_type: "property_tags" requires property_tags - authorization_type: "inline_properties" requires properties - authorization_type: "publisher_properties" requires publisher_properties
For backward compatibility, also validates the old mutual exclusivity constraint.
Args
agent- An agent dict from adagents.json
Raises
ValidationError- If discriminator or field constraints are violated
def validate_product(product: dict[str, Any]) ‑> None-
Expand source code
def validate_product(product: dict[str, Any]) -> None: """Validate a Product object. Args: product: Product dict Raises: ValidationError: If validation fails """ if "publisher_properties" in product and product["publisher_properties"]: for item in product["publisher_properties"]: validate_publisher_properties_item(item) def validate_publisher_properties_item(item: dict[str, Any]) ‑> None-
Expand source code
def validate_publisher_properties_item(item: dict[str, Any]) -> None: """Validate publisher_properties item discriminated union. AdCP v2.4.0+ uses discriminated unions with selection_type discriminator: - selection_type: "by_id" requires property_ids - selection_type: "by_tag" requires property_tags For backward compatibility, also validates the old mutual exclusivity constraint. Args: item: A single item from publisher_properties array Raises: ValidationError: If discriminator or field constraints are violated """ selection_type = item.get("selection_type") has_property_ids = "property_ids" in item and item["property_ids"] is not None has_property_tags = "property_tags" in item and item["property_tags"] is not None # If selection_type discriminator is present, validate discriminated union if selection_type: if selection_type == "by_id" and not has_property_ids: raise ValidationError( "publisher_properties item with selection_type='by_id' must have property_ids" ) elif selection_type == "by_tag" and not has_property_tags: raise ValidationError( "publisher_properties item with selection_type='by_tag' must have property_tags" ) elif selection_type not in ("by_id", "by_tag"): raise ValidationError( f"publisher_properties item has invalid selection_type: {selection_type}" ) # Validate mutual exclusivity (for both old and new formats) if has_property_ids and has_property_tags: raise ValidationError( "publisher_properties item cannot have both property_ids and property_tags. " "These fields are mutually exclusive." ) if not has_property_ids and not has_property_tags: raise ValidationError( "publisher_properties item must have either property_ids or property_tags. " "At least one is required." )Validate publisher_properties item discriminated union.
AdCP v2.4.0+ uses discriminated unions with selection_type discriminator: - selection_type: "by_id" requires property_ids - selection_type: "by_tag" requires property_tags
For backward compatibility, also validates the old mutual exclusivity constraint.
Args
item- A single item from publisher_properties array
Raises
ValidationError- If discriminator or field constraints are violated
-
Expand source code
def verify_agent_authorization( adagents_data: dict[str, Any], agent_url: str, property_type: str | None = None, property_identifiers: list[dict[str, str]] | None = None, ) -> bool: """Check if agent is authorized for a property. Args: adagents_data: Parsed adagents.json data agent_url: URL of the sales agent to verify property_type: Type of property (website, app, etc.) - optional property_identifiers: List of identifiers to match - optional Returns: True if agent is authorized, False otherwise Raises: AdagentsValidationError: If adagents_data is malformed Notes: - If property_type/identifiers are None, checks if agent is authorized for ANY property on this domain - Implements AdCP domain matching rules - Agent URLs are matched ignoring protocol and trailing slash """ # Validate structure if not isinstance(adagents_data, dict): raise AdagentsValidationError("adagents_data must be a dictionary") authorized_agents = adagents_data.get("authorized_agents") if not isinstance(authorized_agents, list): raise AdagentsValidationError("adagents.json must have 'authorized_agents' array") # Normalize the agent URL for comparison normalized_agent_url = normalize_url(agent_url) # Check each authorized agent for agent in authorized_agents: if not isinstance(agent, dict): continue agent_url_from_json = agent.get("url", "") if not agent_url_from_json: continue # Match agent URL (protocol-agnostic) if normalize_url(agent_url_from_json) != normalized_agent_url: continue # Found matching agent - now check properties properties = agent.get("properties") # If properties field is missing or empty, agent is authorized for all properties if properties is None or (isinstance(properties, list) and len(properties) == 0): return True # If no property filters specified, we found the agent - authorized if property_type is None and property_identifiers is None: return True # Check specific property authorization if isinstance(properties, list): for prop in properties: if not isinstance(prop, dict): continue # Check property type if specified if property_type is not None: prop_type = prop.get("property_type", "") if prop_type != property_type: continue # Check identifiers if specified if property_identifiers is not None: prop_identifiers = prop.get("identifiers", []) if not isinstance(prop_identifiers, list): continue if identifiers_match(property_identifiers, prop_identifiers): return True else: # Property type matched and no identifier check needed return True return FalseCheck if agent is authorized for a property.
Args
adagents_data- Parsed adagents.json data
agent_url- URL of the sales agent to verify
property_type- Type of property (website, app, etc.) - optional
property_identifiers- List of identifiers to match - optional
Returns
True if agent is authorized, False otherwise
Raises
AdagentsValidationError- If adagents_data is malformed
Notes
- If property_type/identifiers are None, checks if agent is authorized for ANY property on this domain
- Implements AdCP domain matching rules
- Agent URLs are matched ignoring protocol and trailing slash
async def verify_agent_for_property(publisher_domain: str,
agent_url: str,
property_identifiers: list[dict[str, str]],
property_type: str | None = None,
timeout: float = 10.0,
client: httpx.AsyncClient | None = None) ‑> bool-
Expand source code
async def verify_agent_for_property( publisher_domain: str, agent_url: str, property_identifiers: list[dict[str, str]], property_type: str | None = None, timeout: float = 10.0, client: httpx.AsyncClient | None = None, ) -> bool: """Convenience wrapper to fetch adagents.json and verify authorization in one call. Args: publisher_domain: Domain hosting the adagents.json file agent_url: URL of the sales agent to verify property_identifiers: List of identifiers to match property_type: Type of property (website, app, etc.) - optional timeout: Request timeout in seconds client: Optional httpx.AsyncClient for connection pooling Returns: True if agent is authorized, False otherwise Raises: AdagentsNotFoundError: If adagents.json not found (404) AdagentsValidationError: If JSON is invalid or malformed AdagentsTimeoutError: If request times out """ adagents_data = await fetch_adagents(publisher_domain, timeout=timeout, client=client) return verify_agent_authorization( adagents_data=adagents_data, agent_url=agent_url, property_type=property_type, property_identifiers=property_identifiers, )Convenience wrapper to fetch adagents.json and verify authorization in one call.
Args
publisher_domain- Domain hosting the adagents.json file
agent_url- URL of the sales agent to verify
property_identifiers- List of identifiers to match
property_type- Type of property (website, app, etc.) - optional
timeout- Request timeout in seconds
client- Optional httpx.AsyncClient for connection pooling
Returns
True if agent is authorized, False otherwise
Raises
AdagentsNotFoundError- If adagents.json not found (404)
AdagentsValidationError- If JSON is invalid or malformed
AdagentsTimeoutError- If request times out
Classes
class ADCPAuthenticationError (message: str, agent_id: str | None = None, agent_uri: str | None = None)-
Expand source code
class ADCPAuthenticationError(ADCPError): """Authentication failed (401, 403).""" def __init__(self, message: str, agent_id: str | None = None, agent_uri: str | None = None): """Initialize authentication error.""" suggestion = ( "Check that your auth_token is valid and not expired.\n" " Verify auth_type ('bearer' vs 'token') and auth_header are correct.\n" " Some agents (like Optable) require auth_type='bearer' and " "auth_header='Authorization'" ) super().__init__(message, agent_id, agent_uri, suggestion)Authentication failed (401, 403).
Initialize authentication error.
Ancestors
- ADCPError
- builtins.Exception
- builtins.BaseException
class ADCPClient (agent_config: AgentConfig,
webhook_url_template: str | None = None,
webhook_secret: str | None = None,
on_activity: Callable[[Activity], None] | None = None)-
Expand source code
class ADCPClient: """Client for interacting with a single AdCP agent.""" def __init__( self, agent_config: AgentConfig, webhook_url_template: str | None = None, webhook_secret: str | None = None, on_activity: Callable[[Activity], None] | None = None, ): """ Initialize ADCP client for a single agent. Args: agent_config: Agent configuration webhook_url_template: Template for webhook URLs with {agent_id}, {task_type}, {operation_id} webhook_secret: Secret for webhook signature verification on_activity: Callback for activity events """ self.agent_config = agent_config self.webhook_url_template = webhook_url_template self.webhook_secret = webhook_secret self.on_activity = on_activity # Initialize protocol adapter self.adapter: ProtocolAdapter if agent_config.protocol == Protocol.A2A: self.adapter = A2AAdapter(agent_config) elif agent_config.protocol == Protocol.MCP: self.adapter = MCPAdapter(agent_config) else: raise ValueError(f"Unsupported protocol: {agent_config.protocol}") # Initialize simple API accessor (lazy import to avoid circular dependency) from adcp.simple import SimpleAPI self.simple = SimpleAPI(self) def get_webhook_url(self, task_type: str, operation_id: str) -> str: """Generate webhook URL for a task.""" if not self.webhook_url_template: raise ValueError("webhook_url_template not configured") return self.webhook_url_template.format( agent_id=self.agent_config.id, task_type=task_type, operation_id=operation_id, ) def _emit_activity(self, activity: Activity) -> None: """Emit activity event.""" if self.on_activity: self.on_activity(activity) async def get_products( self, request: GetProductsRequest, fetch_previews: bool = False, preview_output_format: str = "url", creative_agent_client: ADCPClient | None = None, ) -> TaskResult[GetProductsResponse]: """ Get advertising products. Args: request: Request parameters fetch_previews: If True, generate preview URLs for each product's formats (uses batch API for 5-10x performance improvement) preview_output_format: "url" for iframe URLs (default), "html" for direct embedding (2-3x faster, no iframe overhead) creative_agent_client: Client for creative agent (required if fetch_previews=True) Returns: TaskResult containing GetProductsResponse with optional preview URLs in metadata Raises: ValueError: If fetch_previews=True but creative_agent_client is not provided """ if fetch_previews and not creative_agent_client: raise ValueError("creative_agent_client is required when fetch_previews=True") operation_id = create_operation_id() params = request.model_dump(exclude_none=True) self._emit_activity( Activity( type=ActivityType.PROTOCOL_REQUEST, operation_id=operation_id, agent_id=self.agent_config.id, task_type="get_products", timestamp=datetime.now(timezone.utc).isoformat(), ) ) raw_result = await self.adapter.get_products(params) self._emit_activity( Activity( type=ActivityType.PROTOCOL_RESPONSE, operation_id=operation_id, agent_id=self.agent_config.id, task_type="get_products", status=raw_result.status, timestamp=datetime.now(timezone.utc).isoformat(), ) ) result: TaskResult[GetProductsResponse] = self.adapter._parse_response( raw_result, GetProductsResponse ) if fetch_previews and result.success and result.data and creative_agent_client: from adcp.utils.preview_cache import add_preview_urls_to_products products_with_previews = await add_preview_urls_to_products( result.data.products, creative_agent_client, use_batch=True, output_format=preview_output_format, ) result.metadata = result.metadata or {} result.metadata["products_with_previews"] = products_with_previews return result async def list_creative_formats( self, request: ListCreativeFormatsRequest, fetch_previews: bool = False, preview_output_format: str = "url", ) -> TaskResult[ListCreativeFormatsResponse]: """ List supported creative formats. Args: request: Request parameters fetch_previews: If True, generate preview URLs for each format using sample manifests (uses batch API for 5-10x performance improvement) preview_output_format: "url" for iframe URLs (default), "html" for direct embedding (2-3x faster, no iframe overhead) Returns: TaskResult containing ListCreativeFormatsResponse with optional preview URLs in metadata """ operation_id = create_operation_id() params = request.model_dump(exclude_none=True) self._emit_activity( Activity( type=ActivityType.PROTOCOL_REQUEST, operation_id=operation_id, agent_id=self.agent_config.id, task_type="list_creative_formats", timestamp=datetime.now(timezone.utc).isoformat(), ) ) raw_result = await self.adapter.list_creative_formats(params) self._emit_activity( Activity( type=ActivityType.PROTOCOL_RESPONSE, operation_id=operation_id, agent_id=self.agent_config.id, task_type="list_creative_formats", status=raw_result.status, timestamp=datetime.now(timezone.utc).isoformat(), ) ) result: TaskResult[ListCreativeFormatsResponse] = self.adapter._parse_response( raw_result, ListCreativeFormatsResponse ) if fetch_previews and result.success and result.data: from adcp.utils.preview_cache import add_preview_urls_to_formats formats_with_previews = await add_preview_urls_to_formats( result.data.formats, self, use_batch=True, output_format=preview_output_format, ) result.metadata = result.metadata or {} result.metadata["formats_with_previews"] = formats_with_previews return result async def preview_creative( self, request: PreviewCreativeRequest, ) -> TaskResult[PreviewCreativeResponse]: """ Generate preview of a creative manifest. Args: request: Request parameters Returns: TaskResult containing PreviewCreativeResponse with preview URLs """ operation_id = create_operation_id() params = request.model_dump(exclude_none=True) self._emit_activity( Activity( type=ActivityType.PROTOCOL_REQUEST, operation_id=operation_id, agent_id=self.agent_config.id, task_type="preview_creative", timestamp=datetime.now(timezone.utc).isoformat(), ) ) raw_result = await self.adapter.preview_creative(params) # type: ignore[attr-defined] self._emit_activity( Activity( type=ActivityType.PROTOCOL_RESPONSE, operation_id=operation_id, agent_id=self.agent_config.id, task_type="preview_creative", status=raw_result.status, timestamp=datetime.now(timezone.utc).isoformat(), ) ) return self.adapter._parse_response(raw_result, PreviewCreativeResponse) async def sync_creatives( self, request: SyncCreativesRequest, ) -> TaskResult[SyncCreativesResponse]: """ Sync Creatives. Args: request: Request parameters Returns: TaskResult containing SyncCreativesResponse """ operation_id = create_operation_id() params = request.model_dump(exclude_none=True) self._emit_activity( Activity( type=ActivityType.PROTOCOL_REQUEST, operation_id=operation_id, agent_id=self.agent_config.id, task_type="sync_creatives", timestamp=datetime.now(timezone.utc).isoformat(), ) ) raw_result = await self.adapter.sync_creatives(params) self._emit_activity( Activity( type=ActivityType.PROTOCOL_RESPONSE, operation_id=operation_id, agent_id=self.agent_config.id, task_type="sync_creatives", status=raw_result.status, timestamp=datetime.now(timezone.utc).isoformat(), ) ) return self.adapter._parse_response(raw_result, SyncCreativesResponse) async def list_creatives( self, request: ListCreativesRequest, ) -> TaskResult[ListCreativesResponse]: """ List Creatives. Args: request: Request parameters Returns: TaskResult containing ListCreativesResponse """ operation_id = create_operation_id() params = request.model_dump(exclude_none=True) self._emit_activity( Activity( type=ActivityType.PROTOCOL_REQUEST, operation_id=operation_id, agent_id=self.agent_config.id, task_type="list_creatives", timestamp=datetime.now(timezone.utc).isoformat(), ) ) raw_result = await self.adapter.list_creatives(params) self._emit_activity( Activity( type=ActivityType.PROTOCOL_RESPONSE, operation_id=operation_id, agent_id=self.agent_config.id, task_type="list_creatives", status=raw_result.status, timestamp=datetime.now(timezone.utc).isoformat(), ) ) return self.adapter._parse_response(raw_result, ListCreativesResponse) async def get_media_buy_delivery( self, request: GetMediaBuyDeliveryRequest, ) -> TaskResult[GetMediaBuyDeliveryResponse]: """ Get Media Buy Delivery. Args: request: Request parameters Returns: TaskResult containing GetMediaBuyDeliveryResponse """ operation_id = create_operation_id() params = request.model_dump(exclude_none=True) self._emit_activity( Activity( type=ActivityType.PROTOCOL_REQUEST, operation_id=operation_id, agent_id=self.agent_config.id, task_type="get_media_buy_delivery", timestamp=datetime.now(timezone.utc).isoformat(), ) ) raw_result = await self.adapter.get_media_buy_delivery(params) self._emit_activity( Activity( type=ActivityType.PROTOCOL_RESPONSE, operation_id=operation_id, agent_id=self.agent_config.id, task_type="get_media_buy_delivery", status=raw_result.status, timestamp=datetime.now(timezone.utc).isoformat(), ) ) return self.adapter._parse_response(raw_result, GetMediaBuyDeliveryResponse) async def list_authorized_properties( self, request: ListAuthorizedPropertiesRequest, ) -> TaskResult[ListAuthorizedPropertiesResponse]: """ List Authorized Properties. Args: request: Request parameters Returns: TaskResult containing ListAuthorizedPropertiesResponse """ operation_id = create_operation_id() params = request.model_dump(exclude_none=True) self._emit_activity( Activity( type=ActivityType.PROTOCOL_REQUEST, operation_id=operation_id, agent_id=self.agent_config.id, task_type="list_authorized_properties", timestamp=datetime.now(timezone.utc).isoformat(), ) ) raw_result = await self.adapter.list_authorized_properties(params) self._emit_activity( Activity( type=ActivityType.PROTOCOL_RESPONSE, operation_id=operation_id, agent_id=self.agent_config.id, task_type="list_authorized_properties", status=raw_result.status, timestamp=datetime.now(timezone.utc).isoformat(), ) ) return self.adapter._parse_response(raw_result, ListAuthorizedPropertiesResponse) async def get_signals( self, request: GetSignalsRequest, ) -> TaskResult[GetSignalsResponse]: """ Get Signals. Args: request: Request parameters Returns: TaskResult containing GetSignalsResponse """ operation_id = create_operation_id() params = request.model_dump(exclude_none=True) self._emit_activity( Activity( type=ActivityType.PROTOCOL_REQUEST, operation_id=operation_id, agent_id=self.agent_config.id, task_type="get_signals", timestamp=datetime.now(timezone.utc).isoformat(), ) ) raw_result = await self.adapter.get_signals(params) self._emit_activity( Activity( type=ActivityType.PROTOCOL_RESPONSE, operation_id=operation_id, agent_id=self.agent_config.id, task_type="get_signals", status=raw_result.status, timestamp=datetime.now(timezone.utc).isoformat(), ) ) return self.adapter._parse_response(raw_result, GetSignalsResponse) async def activate_signal( self, request: ActivateSignalRequest, ) -> TaskResult[ActivateSignalResponse]: """ Activate Signal. Args: request: Request parameters Returns: TaskResult containing ActivateSignalResponse """ operation_id = create_operation_id() params = request.model_dump(exclude_none=True) self._emit_activity( Activity( type=ActivityType.PROTOCOL_REQUEST, operation_id=operation_id, agent_id=self.agent_config.id, task_type="activate_signal", timestamp=datetime.now(timezone.utc).isoformat(), ) ) raw_result = await self.adapter.activate_signal(params) self._emit_activity( Activity( type=ActivityType.PROTOCOL_RESPONSE, operation_id=operation_id, agent_id=self.agent_config.id, task_type="activate_signal", status=raw_result.status, timestamp=datetime.now(timezone.utc).isoformat(), ) ) return self.adapter._parse_response(raw_result, ActivateSignalResponse) async def provide_performance_feedback( self, request: ProvidePerformanceFeedbackRequest, ) -> TaskResult[ProvidePerformanceFeedbackResponse]: """ Provide Performance Feedback. Args: request: Request parameters Returns: TaskResult containing ProvidePerformanceFeedbackResponse """ operation_id = create_operation_id() params = request.model_dump(exclude_none=True) self._emit_activity( Activity( type=ActivityType.PROTOCOL_REQUEST, operation_id=operation_id, agent_id=self.agent_config.id, task_type="provide_performance_feedback", timestamp=datetime.now(timezone.utc).isoformat(), ) ) raw_result = await self.adapter.provide_performance_feedback(params) self._emit_activity( Activity( type=ActivityType.PROTOCOL_RESPONSE, operation_id=operation_id, agent_id=self.agent_config.id, task_type="provide_performance_feedback", status=raw_result.status, timestamp=datetime.now(timezone.utc).isoformat(), ) ) return self.adapter._parse_response(raw_result, ProvidePerformanceFeedbackResponse) async def list_tools(self) -> list[str]: """ List available tools from the agent. Returns: List of tool names """ return await self.adapter.list_tools() async def close(self) -> None: """Close the adapter and clean up resources.""" if hasattr(self.adapter, "close"): logger.debug(f"Closing adapter for agent {self.agent_config.id}") await self.adapter.close() async def __aenter__(self) -> ADCPClient: """Async context manager entry.""" return self async def __aexit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None: """Async context manager exit.""" await self.close() def _verify_webhook_signature(self, payload: dict[str, Any], signature: str) -> bool: """ Verify HMAC-SHA256 signature of webhook payload. Args: payload: Webhook payload dict signature: Signature to verify Returns: True if signature is valid, False otherwise """ if not self.webhook_secret: return True payload_bytes = json.dumps(payload, separators=(",", ":"), sort_keys=True).encode("utf-8") expected_signature = hmac.new( self.webhook_secret.encode("utf-8"), payload_bytes, hashlib.sha256 ).hexdigest() return hmac.compare_digest(signature, expected_signature) def _parse_webhook_result(self, webhook: WebhookPayload) -> TaskResult[Any]: """ Parse webhook payload into typed TaskResult based on task_type. Args: webhook: Validated webhook payload Returns: TaskResult with task-specific typed response data """ from adcp.utils.response_parser import parse_json_or_text # Map task types to their response types (using string literals, not enum) # Note: Some response types are Union types (e.g., ActivateSignalResponse = Success | Error) response_type_map: dict[str, type[BaseModel] | Any] = { "get_products": GetProductsResponse, "list_creative_formats": ListCreativeFormatsResponse, "sync_creatives": SyncCreativesResponse, # Union type "list_creatives": ListCreativesResponse, "get_media_buy_delivery": GetMediaBuyDeliveryResponse, "list_authorized_properties": ListAuthorizedPropertiesResponse, "get_signals": GetSignalsResponse, "activate_signal": ActivateSignalResponse, # Union type "provide_performance_feedback": ProvidePerformanceFeedbackResponse, } # Handle completed tasks with result parsing if webhook.status == GeneratedTaskStatus.completed and webhook.result is not None: response_type = response_type_map.get(webhook.task_type.value) if response_type: try: parsed_result: Any = parse_json_or_text(webhook.result, response_type) return TaskResult[Any]( status=TaskStatus.COMPLETED, data=parsed_result, success=True, metadata={ "task_id": webhook.task_id, "operation_id": webhook.operation_id, "timestamp": webhook.timestamp, "message": webhook.message, }, ) except ValueError as e: logger.warning(f"Failed to parse webhook result: {e}") # Fall through to untyped result # Handle failed, input-required, or unparseable results # Convert webhook status to core TaskStatus enum # Map generated enum values to core enum values status_map = { GeneratedTaskStatus.completed: TaskStatus.COMPLETED, GeneratedTaskStatus.submitted: TaskStatus.SUBMITTED, GeneratedTaskStatus.working: TaskStatus.WORKING, GeneratedTaskStatus.failed: TaskStatus.FAILED, GeneratedTaskStatus.input_required: TaskStatus.NEEDS_INPUT, } task_status = status_map.get(webhook.status, TaskStatus.FAILED) return TaskResult[Any]( status=task_status, data=webhook.result, success=webhook.status == GeneratedTaskStatus.completed, error=webhook.error if isinstance(webhook.error, str) else None, metadata={ "task_id": webhook.task_id, "operation_id": webhook.operation_id, "timestamp": webhook.timestamp, "message": webhook.message, "context_id": webhook.context_id, "progress": webhook.progress, }, ) async def handle_webhook( self, payload: dict[str, Any], signature: str | None = None, ) -> TaskResult[Any]: """ Handle incoming webhook and return typed result. This method: 1. Verifies webhook signature (if provided) 2. Validates payload against WebhookPayload schema 3. Parses task-specific result data into typed response 4. Emits activity for monitoring Args: payload: Webhook payload dict signature: Optional HMAC-SHA256 signature for verification Returns: TaskResult with parsed task-specific response data Raises: ADCPWebhookSignatureError: If signature verification fails ValidationError: If payload doesn't match WebhookPayload schema Example: >>> result = await client.handle_webhook(payload, signature) >>> if result.success and isinstance(result.data, GetProductsResponse): >>> print(f"Found {len(result.data.products)} products") """ # Verify signature before processing if signature and not self._verify_webhook_signature(payload, signature): logger.warning( f"Webhook signature verification failed for agent {self.agent_config.id}" ) raise ADCPWebhookSignatureError("Invalid webhook signature") # Validate and parse webhook payload webhook = WebhookPayload.model_validate(payload) # Emit activity for monitoring self._emit_activity( Activity( type=ActivityType.WEBHOOK_RECEIVED, operation_id=webhook.operation_id or "unknown", agent_id=self.agent_config.id, task_type=webhook.task_type.value, timestamp=datetime.now(timezone.utc).isoformat(), metadata={"payload": payload}, ) ) # Parse and return typed result return self._parse_webhook_result(webhook)Client for interacting with a single AdCP agent.
Initialize ADCP client for a single agent.
Args
agent_config- Agent configuration
webhook_url_template- Template for webhook URLs with {agent_id}, {task_type}, {operation_id}
webhook_secret- Secret for webhook signature verification
on_activity- Callback for activity events
Methods
async def activate_signal(self,
request: ActivateSignalRequest) ‑> TaskResult[ActivateSignalResponse]-
Expand source code
async def activate_signal( self, request: ActivateSignalRequest, ) -> TaskResult[ActivateSignalResponse]: """ Activate Signal. Args: request: Request parameters Returns: TaskResult containing ActivateSignalResponse """ operation_id = create_operation_id() params = request.model_dump(exclude_none=True) self._emit_activity( Activity( type=ActivityType.PROTOCOL_REQUEST, operation_id=operation_id, agent_id=self.agent_config.id, task_type="activate_signal", timestamp=datetime.now(timezone.utc).isoformat(), ) ) raw_result = await self.adapter.activate_signal(params) self._emit_activity( Activity( type=ActivityType.PROTOCOL_RESPONSE, operation_id=operation_id, agent_id=self.agent_config.id, task_type="activate_signal", status=raw_result.status, timestamp=datetime.now(timezone.utc).isoformat(), ) ) return self.adapter._parse_response(raw_result, ActivateSignalResponse)Activate Signal.
Args
request- Request parameters
Returns
TaskResult containing ActivateSignalResponse
async def close(self) ‑> None-
Expand source code
async def close(self) -> None: """Close the adapter and clean up resources.""" if hasattr(self.adapter, "close"): logger.debug(f"Closing adapter for agent {self.agent_config.id}") await self.adapter.close()Close the adapter and clean up resources.
async def get_media_buy_delivery(self,
request: GetMediaBuyDeliveryRequest) ‑> TaskResult[GetMediaBuyDeliveryResponse]-
Expand source code
async def get_media_buy_delivery( self, request: GetMediaBuyDeliveryRequest, ) -> TaskResult[GetMediaBuyDeliveryResponse]: """ Get Media Buy Delivery. Args: request: Request parameters Returns: TaskResult containing GetMediaBuyDeliveryResponse """ operation_id = create_operation_id() params = request.model_dump(exclude_none=True) self._emit_activity( Activity( type=ActivityType.PROTOCOL_REQUEST, operation_id=operation_id, agent_id=self.agent_config.id, task_type="get_media_buy_delivery", timestamp=datetime.now(timezone.utc).isoformat(), ) ) raw_result = await self.adapter.get_media_buy_delivery(params) self._emit_activity( Activity( type=ActivityType.PROTOCOL_RESPONSE, operation_id=operation_id, agent_id=self.agent_config.id, task_type="get_media_buy_delivery", status=raw_result.status, timestamp=datetime.now(timezone.utc).isoformat(), ) ) return self.adapter._parse_response(raw_result, GetMediaBuyDeliveryResponse)Get Media Buy Delivery.
Args
request- Request parameters
Returns
TaskResult containing GetMediaBuyDeliveryResponse
async def get_products(self,
request: GetProductsRequest,
fetch_previews: bool = False,
preview_output_format: str = 'url',
creative_agent_client: ADCPClient | None = None) ‑> TaskResult[GetProductsResponse]-
Expand source code
async def get_products( self, request: GetProductsRequest, fetch_previews: bool = False, preview_output_format: str = "url", creative_agent_client: ADCPClient | None = None, ) -> TaskResult[GetProductsResponse]: """ Get advertising products. Args: request: Request parameters fetch_previews: If True, generate preview URLs for each product's formats (uses batch API for 5-10x performance improvement) preview_output_format: "url" for iframe URLs (default), "html" for direct embedding (2-3x faster, no iframe overhead) creative_agent_client: Client for creative agent (required if fetch_previews=True) Returns: TaskResult containing GetProductsResponse with optional preview URLs in metadata Raises: ValueError: If fetch_previews=True but creative_agent_client is not provided """ if fetch_previews and not creative_agent_client: raise ValueError("creative_agent_client is required when fetch_previews=True") operation_id = create_operation_id() params = request.model_dump(exclude_none=True) self._emit_activity( Activity( type=ActivityType.PROTOCOL_REQUEST, operation_id=operation_id, agent_id=self.agent_config.id, task_type="get_products", timestamp=datetime.now(timezone.utc).isoformat(), ) ) raw_result = await self.adapter.get_products(params) self._emit_activity( Activity( type=ActivityType.PROTOCOL_RESPONSE, operation_id=operation_id, agent_id=self.agent_config.id, task_type="get_products", status=raw_result.status, timestamp=datetime.now(timezone.utc).isoformat(), ) ) result: TaskResult[GetProductsResponse] = self.adapter._parse_response( raw_result, GetProductsResponse ) if fetch_previews and result.success and result.data and creative_agent_client: from adcp.utils.preview_cache import add_preview_urls_to_products products_with_previews = await add_preview_urls_to_products( result.data.products, creative_agent_client, use_batch=True, output_format=preview_output_format, ) result.metadata = result.metadata or {} result.metadata["products_with_previews"] = products_with_previews return resultGet advertising products.
Args
request- Request parameters
fetch_previews- If True, generate preview URLs for each product's formats (uses batch API for 5-10x performance improvement)
preview_output_format- "url" for iframe URLs (default), "html" for direct embedding (2-3x faster, no iframe overhead)
creative_agent_client- Client for creative agent (required if fetch_previews=True)
Returns
TaskResult containing GetProductsResponse with optional preview URLs in metadata
Raises
ValueError- If fetch_previews=True but creative_agent_client is not provided
async def get_signals(self,
request: GetSignalsRequest) ‑> TaskResult[GetSignalsResponse]-
Expand source code
async def get_signals( self, request: GetSignalsRequest, ) -> TaskResult[GetSignalsResponse]: """ Get Signals. Args: request: Request parameters Returns: TaskResult containing GetSignalsResponse """ operation_id = create_operation_id() params = request.model_dump(exclude_none=True) self._emit_activity( Activity( type=ActivityType.PROTOCOL_REQUEST, operation_id=operation_id, agent_id=self.agent_config.id, task_type="get_signals", timestamp=datetime.now(timezone.utc).isoformat(), ) ) raw_result = await self.adapter.get_signals(params) self._emit_activity( Activity( type=ActivityType.PROTOCOL_RESPONSE, operation_id=operation_id, agent_id=self.agent_config.id, task_type="get_signals", status=raw_result.status, timestamp=datetime.now(timezone.utc).isoformat(), ) ) return self.adapter._parse_response(raw_result, GetSignalsResponse)Get Signals.
Args
request- Request parameters
Returns
TaskResult containing GetSignalsResponse
def get_webhook_url(self, task_type: str, operation_id: str) ‑> str-
Expand source code
def get_webhook_url(self, task_type: str, operation_id: str) -> str: """Generate webhook URL for a task.""" if not self.webhook_url_template: raise ValueError("webhook_url_template not configured") return self.webhook_url_template.format( agent_id=self.agent_config.id, task_type=task_type, operation_id=operation_id, )Generate webhook URL for a task.
async def handle_webhook(self, payload: dict[str, Any], signature: str | None = None) ‑> TaskResult[Any]-
Expand source code
async def handle_webhook( self, payload: dict[str, Any], signature: str | None = None, ) -> TaskResult[Any]: """ Handle incoming webhook and return typed result. This method: 1. Verifies webhook signature (if provided) 2. Validates payload against WebhookPayload schema 3. Parses task-specific result data into typed response 4. Emits activity for monitoring Args: payload: Webhook payload dict signature: Optional HMAC-SHA256 signature for verification Returns: TaskResult with parsed task-specific response data Raises: ADCPWebhookSignatureError: If signature verification fails ValidationError: If payload doesn't match WebhookPayload schema Example: >>> result = await client.handle_webhook(payload, signature) >>> if result.success and isinstance(result.data, GetProductsResponse): >>> print(f"Found {len(result.data.products)} products") """ # Verify signature before processing if signature and not self._verify_webhook_signature(payload, signature): logger.warning( f"Webhook signature verification failed for agent {self.agent_config.id}" ) raise ADCPWebhookSignatureError("Invalid webhook signature") # Validate and parse webhook payload webhook = WebhookPayload.model_validate(payload) # Emit activity for monitoring self._emit_activity( Activity( type=ActivityType.WEBHOOK_RECEIVED, operation_id=webhook.operation_id or "unknown", agent_id=self.agent_config.id, task_type=webhook.task_type.value, timestamp=datetime.now(timezone.utc).isoformat(), metadata={"payload": payload}, ) ) # Parse and return typed result return self._parse_webhook_result(webhook)Handle incoming webhook and return typed result.
This method: 1. Verifies webhook signature (if provided) 2. Validates payload against WebhookPayload schema 3. Parses task-specific result data into typed response 4. Emits activity for monitoring
Args
payload- Webhook payload dict
signature- Optional HMAC-SHA256 signature for verification
Returns
TaskResult with parsed task-specific response data
Raises
ADCPWebhookSignatureError- If signature verification fails
ValidationError- If payload doesn't match WebhookPayload schema
Example
>>> result = await client.handle_webhook(payload, signature) >>> if result.success and isinstance(result.data, GetProductsResponse): >>> print(f"Found {len(result.data.products)} products") -
Expand source code
async def list_authorized_properties( self, request: ListAuthorizedPropertiesRequest, ) -> TaskResult[ListAuthorizedPropertiesResponse]: """ List Authorized Properties. Args: request: Request parameters Returns: TaskResult containing ListAuthorizedPropertiesResponse """ operation_id = create_operation_id() params = request.model_dump(exclude_none=True) self._emit_activity( Activity( type=ActivityType.PROTOCOL_REQUEST, operation_id=operation_id, agent_id=self.agent_config.id, task_type="list_authorized_properties", timestamp=datetime.now(timezone.utc).isoformat(), ) ) raw_result = await self.adapter.list_authorized_properties(params) self._emit_activity( Activity( type=ActivityType.PROTOCOL_RESPONSE, operation_id=operation_id, agent_id=self.agent_config.id, task_type="list_authorized_properties", status=raw_result.status, timestamp=datetime.now(timezone.utc).isoformat(), ) ) return self.adapter._parse_response(raw_result, ListAuthorizedPropertiesResponse)List Authorized Properties.
Args
request- Request parameters
Returns
TaskResult containing ListAuthorizedPropertiesResponse
async def list_creative_formats(self,
request: ListCreativeFormatsRequest,
fetch_previews: bool = False,
preview_output_format: str = 'url') ‑> TaskResult[ListCreativeFormatsResponse]-
Expand source code
async def list_creative_formats( self, request: ListCreativeFormatsRequest, fetch_previews: bool = False, preview_output_format: str = "url", ) -> TaskResult[ListCreativeFormatsResponse]: """ List supported creative formats. Args: request: Request parameters fetch_previews: If True, generate preview URLs for each format using sample manifests (uses batch API for 5-10x performance improvement) preview_output_format: "url" for iframe URLs (default), "html" for direct embedding (2-3x faster, no iframe overhead) Returns: TaskResult containing ListCreativeFormatsResponse with optional preview URLs in metadata """ operation_id = create_operation_id() params = request.model_dump(exclude_none=True) self._emit_activity( Activity( type=ActivityType.PROTOCOL_REQUEST, operation_id=operation_id, agent_id=self.agent_config.id, task_type="list_creative_formats", timestamp=datetime.now(timezone.utc).isoformat(), ) ) raw_result = await self.adapter.list_creative_formats(params) self._emit_activity( Activity( type=ActivityType.PROTOCOL_RESPONSE, operation_id=operation_id, agent_id=self.agent_config.id, task_type="list_creative_formats", status=raw_result.status, timestamp=datetime.now(timezone.utc).isoformat(), ) ) result: TaskResult[ListCreativeFormatsResponse] = self.adapter._parse_response( raw_result, ListCreativeFormatsResponse ) if fetch_previews and result.success and result.data: from adcp.utils.preview_cache import add_preview_urls_to_formats formats_with_previews = await add_preview_urls_to_formats( result.data.formats, self, use_batch=True, output_format=preview_output_format, ) result.metadata = result.metadata or {} result.metadata["formats_with_previews"] = formats_with_previews return resultList supported creative formats.
Args
request- Request parameters
fetch_previews- If True, generate preview URLs for each format using sample manifests (uses batch API for 5-10x performance improvement)
preview_output_format- "url" for iframe URLs (default), "html" for direct embedding (2-3x faster, no iframe overhead)
Returns
TaskResult containing ListCreativeFormatsResponse with optional preview URLs in metadata
async def list_creatives(self,
request: ListCreativesRequest) ‑> TaskResult[ListCreativesResponse]-
Expand source code
async def list_creatives( self, request: ListCreativesRequest, ) -> TaskResult[ListCreativesResponse]: """ List Creatives. Args: request: Request parameters Returns: TaskResult containing ListCreativesResponse """ operation_id = create_operation_id() params = request.model_dump(exclude_none=True) self._emit_activity( Activity( type=ActivityType.PROTOCOL_REQUEST, operation_id=operation_id, agent_id=self.agent_config.id, task_type="list_creatives", timestamp=datetime.now(timezone.utc).isoformat(), ) ) raw_result = await self.adapter.list_creatives(params) self._emit_activity( Activity( type=ActivityType.PROTOCOL_RESPONSE, operation_id=operation_id, agent_id=self.agent_config.id, task_type="list_creatives", status=raw_result.status, timestamp=datetime.now(timezone.utc).isoformat(), ) ) return self.adapter._parse_response(raw_result, ListCreativesResponse)List Creatives.
Args
request- Request parameters
Returns
TaskResult containing ListCreativesResponse
async def list_tools(self) ‑> list[str]-
Expand source code
async def list_tools(self) -> list[str]: """ List available tools from the agent. Returns: List of tool names """ return await self.adapter.list_tools()List available tools from the agent.
Returns
List of tool names
async def preview_creative(self,
request: PreviewCreativeRequest) ‑> TaskResult[PreviewCreativeResponse]-
Expand source code
async def preview_creative( self, request: PreviewCreativeRequest, ) -> TaskResult[PreviewCreativeResponse]: """ Generate preview of a creative manifest. Args: request: Request parameters Returns: TaskResult containing PreviewCreativeResponse with preview URLs """ operation_id = create_operation_id() params = request.model_dump(exclude_none=True) self._emit_activity( Activity( type=ActivityType.PROTOCOL_REQUEST, operation_id=operation_id, agent_id=self.agent_config.id, task_type="preview_creative", timestamp=datetime.now(timezone.utc).isoformat(), ) ) raw_result = await self.adapter.preview_creative(params) # type: ignore[attr-defined] self._emit_activity( Activity( type=ActivityType.PROTOCOL_RESPONSE, operation_id=operation_id, agent_id=self.agent_config.id, task_type="preview_creative", status=raw_result.status, timestamp=datetime.now(timezone.utc).isoformat(), ) ) return self.adapter._parse_response(raw_result, PreviewCreativeResponse)Generate preview of a creative manifest.
Args
request- Request parameters
Returns
TaskResult containing PreviewCreativeResponse with preview URLs
async def provide_performance_feedback(self,
request: ProvidePerformanceFeedbackRequest) ‑> TaskResult[ProvidePerformanceFeedbackResponse]-
Expand source code
async def provide_performance_feedback( self, request: ProvidePerformanceFeedbackRequest, ) -> TaskResult[ProvidePerformanceFeedbackResponse]: """ Provide Performance Feedback. Args: request: Request parameters Returns: TaskResult containing ProvidePerformanceFeedbackResponse """ operation_id = create_operation_id() params = request.model_dump(exclude_none=True) self._emit_activity( Activity( type=ActivityType.PROTOCOL_REQUEST, operation_id=operation_id, agent_id=self.agent_config.id, task_type="provide_performance_feedback", timestamp=datetime.now(timezone.utc).isoformat(), ) ) raw_result = await self.adapter.provide_performance_feedback(params) self._emit_activity( Activity( type=ActivityType.PROTOCOL_RESPONSE, operation_id=operation_id, agent_id=self.agent_config.id, task_type="provide_performance_feedback", status=raw_result.status, timestamp=datetime.now(timezone.utc).isoformat(), ) ) return self.adapter._parse_response(raw_result, ProvidePerformanceFeedbackResponse)Provide Performance Feedback.
Args
request- Request parameters
Returns
TaskResult containing ProvidePerformanceFeedbackResponse
async def sync_creatives(self,
request: SyncCreativesRequest) ‑> TaskResult[SyncCreativesResponse]-
Expand source code
async def sync_creatives( self, request: SyncCreativesRequest, ) -> TaskResult[SyncCreativesResponse]: """ Sync Creatives. Args: request: Request parameters Returns: TaskResult containing SyncCreativesResponse """ operation_id = create_operation_id() params = request.model_dump(exclude_none=True) self._emit_activity( Activity( type=ActivityType.PROTOCOL_REQUEST, operation_id=operation_id, agent_id=self.agent_config.id, task_type="sync_creatives", timestamp=datetime.now(timezone.utc).isoformat(), ) ) raw_result = await self.adapter.sync_creatives(params) self._emit_activity( Activity( type=ActivityType.PROTOCOL_RESPONSE, operation_id=operation_id, agent_id=self.agent_config.id, task_type="sync_creatives", status=raw_result.status, timestamp=datetime.now(timezone.utc).isoformat(), ) ) return self.adapter._parse_response(raw_result, SyncCreativesResponse)Sync Creatives.
Args
request- Request parameters
Returns
TaskResult containing SyncCreativesResponse
class ADCPConnectionError (message: str, agent_id: str | None = None, agent_uri: str | None = None)-
Expand source code
class ADCPConnectionError(ADCPError): """Connection to agent failed.""" def __init__(self, message: str, agent_id: str | None = None, agent_uri: str | None = None): """Initialize connection error.""" suggestion = ( "Check that the agent URI is correct and the agent is running.\n" " Try testing with: python -m adcp test --config <agent-id>" ) super().__init__(message, agent_id, agent_uri, suggestion)Connection to agent failed.
Initialize connection error.
Ancestors
- ADCPError
- builtins.Exception
- builtins.BaseException
class ADCPError (message: str,
agent_id: str | None = None,
agent_uri: str | None = None,
suggestion: str | None = None)-
Expand source code
class ADCPError(Exception): """Base exception for all AdCP client errors.""" def __init__( self, message: str, agent_id: str | None = None, agent_uri: str | None = None, suggestion: str | None = None, ): """Initialize exception with context.""" self.message = message self.agent_id = agent_id self.agent_uri = agent_uri self.suggestion = suggestion full_message = message if agent_id: full_message = f"[Agent: {agent_id}] {full_message}" if agent_uri: full_message = f"{full_message}\n URI: {agent_uri}" if suggestion: full_message = f"{full_message}\n 💡 {suggestion}" super().__init__(full_message)Base exception for all AdCP client errors.
Initialize exception with context.
Ancestors
- builtins.Exception
- builtins.BaseException
Subclasses
class ADCPMultiAgentClient (agents: list[AgentConfig],
webhook_url_template: str | None = None,
webhook_secret: str | None = None,
on_activity: Callable[[Activity], None] | None = None,
handlers: dict[str, Callable[..., Any]] | None = None)-
Expand source code
class ADCPMultiAgentClient: """Client for managing multiple AdCP agents.""" def __init__( self, agents: list[AgentConfig], webhook_url_template: str | None = None, webhook_secret: str | None = None, on_activity: Callable[[Activity], None] | None = None, handlers: dict[str, Callable[..., Any]] | None = None, ): """ Initialize multi-agent client. Args: agents: List of agent configurations webhook_url_template: Template for webhook URLs webhook_secret: Secret for webhook verification on_activity: Callback for activity events handlers: Task completion handlers """ self.agents = { agent.id: ADCPClient( agent, webhook_url_template=webhook_url_template, webhook_secret=webhook_secret, on_activity=on_activity, ) for agent in agents } self.handlers = handlers or {} def agent(self, agent_id: str) -> ADCPClient: """Get client for specific agent.""" if agent_id not in self.agents: raise ValueError(f"Agent not found: {agent_id}") return self.agents[agent_id] @property def agent_ids(self) -> list[str]: """Get list of agent IDs.""" return list(self.agents.keys()) async def close(self) -> None: """Close all agent clients and clean up resources.""" import asyncio logger.debug("Closing all agent clients in multi-agent client") close_tasks = [client.close() for client in self.agents.values()] await asyncio.gather(*close_tasks, return_exceptions=True) async def __aenter__(self) -> ADCPMultiAgentClient: """Async context manager entry.""" return self async def __aexit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None: """Async context manager exit.""" await self.close() async def get_products( self, request: GetProductsRequest, ) -> list[TaskResult[GetProductsResponse]]: """ Execute get_products across all agents in parallel. Args: request: Request parameters Returns: List of TaskResults containing GetProductsResponse for each agent """ import asyncio tasks = [agent.get_products(request) for agent in self.agents.values()] return await asyncio.gather(*tasks) @classmethod def from_env(cls) -> ADCPMultiAgentClient: """Create client from environment variables.""" agents_json = os.getenv("ADCP_AGENTS") if not agents_json: raise ValueError("ADCP_AGENTS environment variable not set") agents_data = json.loads(agents_json) agents = [AgentConfig(**agent) for agent in agents_data] return cls( agents=agents, webhook_url_template=os.getenv("WEBHOOK_URL_TEMPLATE"), webhook_secret=os.getenv("WEBHOOK_SECRET"), )Client for managing multiple AdCP agents.
Initialize multi-agent client.
Args
agents- List of agent configurations
webhook_url_template- Template for webhook URLs
webhook_secret- Secret for webhook verification
on_activity- Callback for activity events
handlers- Task completion handlers
Static methods
def from_env() ‑> ADCPMultiAgentClient-
Create client from environment variables.
Instance variables
prop agent_ids : list[str]-
Expand source code
@property def agent_ids(self) -> list[str]: """Get list of agent IDs.""" return list(self.agents.keys())Get list of agent IDs.
Methods
def agent(self, agent_id: str) ‑> ADCPClient-
Expand source code
def agent(self, agent_id: str) -> ADCPClient: """Get client for specific agent.""" if agent_id not in self.agents: raise ValueError(f"Agent not found: {agent_id}") return self.agents[agent_id]Get client for specific agent.
async def close(self) ‑> None-
Expand source code
async def close(self) -> None: """Close all agent clients and clean up resources.""" import asyncio logger.debug("Closing all agent clients in multi-agent client") close_tasks = [client.close() for client in self.agents.values()] await asyncio.gather(*close_tasks, return_exceptions=True)Close all agent clients and clean up resources.
async def get_products(self,
request: GetProductsRequest) ‑> list[TaskResult[GetProductsResponse]]-
Expand source code
async def get_products( self, request: GetProductsRequest, ) -> list[TaskResult[GetProductsResponse]]: """ Execute get_products across all agents in parallel. Args: request: Request parameters Returns: List of TaskResults containing GetProductsResponse for each agent """ import asyncio tasks = [agent.get_products(request) for agent in self.agents.values()] return await asyncio.gather(*tasks)Execute get_products across all agents in parallel.
Args
request- Request parameters
Returns
List of TaskResults containing GetProductsResponse for each agent
class ADCPProtocolError (message: str, agent_id: str | None = None, protocol: str | None = None)-
Expand source code
class ADCPProtocolError(ADCPError): """Protocol-level error (malformed response, unexpected format).""" def __init__(self, message: str, agent_id: str | None = None, protocol: str | None = None): """Initialize protocol error.""" suggestion = ( f"The agent returned an unexpected {protocol} response format." if protocol else "Unexpected response format." ) suggestion += "\n Enable debug mode to see the full request/response." super().__init__(message, agent_id, None, suggestion)Protocol-level error (malformed response, unexpected format).
Initialize protocol error.
Ancestors
- ADCPError
- builtins.Exception
- builtins.BaseException
class ADCPTimeoutError (message: str,
agent_id: str | None = None,
agent_uri: str | None = None,
timeout: float | None = None)-
Expand source code
class ADCPTimeoutError(ADCPError): """Request timed out.""" def __init__( self, message: str, agent_id: str | None = None, agent_uri: str | None = None, timeout: float | None = None, ): """Initialize timeout error.""" suggestion = ( f"The request took longer than {timeout}s." if timeout else "The request timed out." ) suggestion += "\n Try increasing the timeout value or check if the agent is overloaded." super().__init__(message, agent_id, agent_uri, suggestion)Request timed out.
Initialize timeout error.
Ancestors
- ADCPError
- builtins.Exception
- builtins.BaseException
class ADCPToolNotFoundError (tool_name: str,
agent_id: str | None = None,
available_tools: list[str] | None = None)-
Expand source code
class ADCPToolNotFoundError(ADCPError): """Requested tool not found on agent.""" def __init__( self, tool_name: str, agent_id: str | None = None, available_tools: list[str] | None = None ): """Initialize tool not found error.""" message = f"Tool '{tool_name}' not found on agent" suggestion = "List available tools with: python -m adcp list-tools --config <agent-id>" if available_tools: tools_list = ", ".join(available_tools[:5]) if len(available_tools) > 5: tools_list += f", ... ({len(available_tools)} total)" suggestion = f"Available tools: {tools_list}" super().__init__(message, agent_id, None, suggestion)Requested tool not found on agent.
Initialize tool not found error.
Ancestors
- ADCPError
- builtins.Exception
- builtins.BaseException
class ADCPWebhookError (message: str,
agent_id: str | None = None,
agent_uri: str | None = None,
suggestion: str | None = None)-
Expand source code
class ADCPWebhookError(ADCPError): """Webhook handling error."""Webhook handling error.
Initialize exception with context.
Ancestors
- ADCPError
- builtins.Exception
- builtins.BaseException
Subclasses
class ADCPWebhookSignatureError (message: str = 'Invalid webhook signature', agent_id: str | None = None)-
Expand source code
class ADCPWebhookSignatureError(ADCPWebhookError): """Webhook signature verification failed.""" def __init__(self, message: str = "Invalid webhook signature", agent_id: str | None = None): """Initialize webhook signature error.""" suggestion = ( "Verify that the webhook_secret matches the secret configured on the agent.\n" " Webhook signatures use HMAC-SHA256 for security." ) super().__init__(message, agent_id, None, suggestion)Webhook signature verification failed.
Initialize webhook signature error.
Ancestors
- ADCPWebhookError
- ADCPError
- builtins.Exception
- builtins.BaseException
class ActivateSignalRequest (**data: Any)-
Expand source code
class ActivateSignalRequest(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context included in the request payload. Agents must echo this value back unchanged in responses and webhooks. Use for UI/session hints, correlation tokens, or tracking metadata.' ), ] = None destinations: Annotated[ list[destination.Destination1 | destination.Destination2], Field( description='Target destination(s) for activation. If the authenticated caller matches one of these destinations, activation keys will be included in the response.', min_length=1, ), ] signal_agent_segment_id: Annotated[ str, Field(description='The universal identifier for the signal to activate') ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : dict[str, typing.Any] | Nonevar destinations : list[Destination1 | Destination2]var model_configvar signal_agent_segment_id : str
Inherited members
class ActivateSignalResponse (root: RootModelRootType = PydanticUndefined, **data)-
Expand source code
class ActivateSignalResponse(RootModel[ActivateSignalResponse1 | ActivateSignalResponse2]): root: Annotated[ ActivateSignalResponse1 | ActivateSignalResponse2, Field( description='Response payload for activate_signal task. Returns either complete success data OR error information, never both. This enforces atomic operation semantics - the signal is either fully activated or not activated at all.', title='Activate Signal Response', ), ]Usage Documentation
A Pydantic
BaseModelfor the root object of the model.Attributes
root- The root object of the model.
__pydantic_root_model__- Whether the model is a RootModel.
__pydantic_private__- Private fields in the model.
__pydantic_extra__- Extra fields in the model.
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- pydantic.root_model.RootModel[Union[ActivateSignalResponse1, ActivateSignalResponse2]]
- pydantic.root_model.RootModel
- pydantic.main.BaseModel
- typing.Generic
Class variables
var model_configvar root : ActivateSignalResponse1 | ActivateSignalResponse2
class ActivateSignalSuccessResponse (**data: Any)-
Expand source code
class ActivateSignalResponse1(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context echoed inside the task payload. Opaque metadata such as UI/session hints, correlation tokens, or tracking identifiers.' ), ] = None deployments: Annotated[ list[deployment.Deployment1 | deployment.Deployment2], Field(description='Array of deployment results for each destination'), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : dict[str, typing.Any] | Nonevar deployments : list[Deployment1 | Deployment2]var model_config
Inherited members
class ActivateSignalErrorResponse (**data: Any)-
Expand source code
class ActivateSignalResponse2(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context echoed inside the task payload. Opaque metadata such as UI/session hints, correlation tokens, or tracking identifiers.' ), ] = None errors: Annotated[ list[error.Error], Field( description='Array of errors explaining why activation failed (e.g., platform connectivity issues, signal definition problems, authentication failures)', min_length=1, ), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : dict[str, typing.Any] | Nonevar errors : list[Error]var model_config
Inherited members
class PropertyIdActivationKey (**data: Any)-
Expand source code
class ActivationKey1(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) segment_id: Annotated[ str, Field(description='The platform-specific segment identifier to use in campaign targeting'), ] type: Annotated[Literal['segment_id'], Field(description='Segment ID based targeting')]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var model_configvar segment_id : strvar type : Literal['segment_id']
Inherited members
class PropertyTagActivationKey (**data: Any)-
Expand source code
class ActivationKey2(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) key: Annotated[str, Field(description='The targeting parameter key')] type: Annotated[Literal['key_value'], Field(description='Key-value pair based targeting')] value: Annotated[str, Field(description='The targeting parameter value')]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var key : strvar model_configvar type : Literal['key_value']var value : str
Inherited members
class AdagentsNotFoundError (publisher_domain: str)-
Expand source code
class AdagentsNotFoundError(AdagentsValidationError): """adagents.json file not found (404).""" def __init__(self, publisher_domain: str): """Initialize not found error.""" message = f"adagents.json not found for domain: {publisher_domain}" suggestion = ( "Verify that the publisher has deployed adagents.json to:\n" f" https://{publisher_domain}/.well-known/adagents.json" ) super().__init__(message, None, None, suggestion)adagents.json file not found (404).
Initialize not found error.
Ancestors
- AdagentsValidationError
- ADCPError
- builtins.Exception
- builtins.BaseException
class AdagentsTimeoutError (publisher_domain: str, timeout: float)-
Expand source code
class AdagentsTimeoutError(AdagentsValidationError): """Request for adagents.json timed out.""" def __init__(self, publisher_domain: str, timeout: float): """Initialize timeout error.""" message = f"Request to fetch adagents.json timed out after {timeout}s" suggestion = ( "The publisher's server may be slow or unresponsive.\n" " Try increasing the timeout value or check the domain is correct." ) super().__init__(message, None, None, suggestion)Request for adagents.json timed out.
Initialize timeout error.
Ancestors
- AdagentsValidationError
- ADCPError
- builtins.Exception
- builtins.BaseException
class AdagentsValidationError (message: str,
agent_id: str | None = None,
agent_uri: str | None = None,
suggestion: str | None = None)-
Expand source code
class AdagentsValidationError(ADCPError): """Base error for adagents.json validation issues."""Base error for adagents.json validation issues.
Initialize exception with context.
Ancestors
- ADCPError
- builtins.Exception
- builtins.BaseException
Subclasses
class AgentConfig (**data: Any)-
Expand source code
class AgentConfig(BaseModel): """Agent configuration.""" id: str agent_uri: str protocol: Protocol auth_token: str | None = None requires_auth: bool = False auth_header: str = "x-adcp-auth" # Header name for authentication auth_type: str = "token" # "token" for direct value, "bearer" for "Bearer {token}" timeout: float = 30.0 # Request timeout in seconds mcp_transport: str = ( "streamable_http" # "streamable_http" (default, modern) or "sse" (legacy fallback) ) debug: bool = False # Enable debug mode to capture request/response details @field_validator("agent_uri") @classmethod def validate_agent_uri(cls, v: str) -> str: """Validate agent URI format.""" if not v: raise ValueError("agent_uri cannot be empty") if not v.startswith(("http://", "https://")): raise ValueError( f"agent_uri must start with http:// or https://, got: {v}\n" "Example: https://agent.example.com" ) # Remove trailing slash for consistency return v.rstrip("/") @field_validator("timeout") @classmethod def validate_timeout(cls, v: float) -> float: """Validate timeout is reasonable.""" if v <= 0: raise ValueError(f"timeout must be positive, got: {v}") if v > 300: # 5 minutes raise ValueError( f"timeout is very large ({v}s). Consider a value under 300 seconds.\n" "Large timeouts can cause long hangs if agent is unresponsive." ) return v @field_validator("mcp_transport") @classmethod def validate_mcp_transport(cls, v: str) -> str: """Validate MCP transport type.""" valid_transports = ["streamable_http", "sse"] if v not in valid_transports: raise ValueError( f"mcp_transport must be one of {valid_transports}, got: {v}\n" "Use 'streamable_http' for modern agents (recommended)" ) return v @field_validator("auth_type") @classmethod def validate_auth_type(cls, v: str) -> str: """Validate auth type.""" valid_types = ["token", "bearer"] if v not in valid_types: raise ValueError( f"auth_type must be one of {valid_types}, got: {v}\n" "Use 'bearer' for OAuth2/standard Authorization header" ) return vAgent configuration.
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- pydantic.main.BaseModel
Class variables
var agent_uri : strvar auth_header : strvar auth_token : str | Nonevar auth_type : strvar debug : boolvar id : strvar mcp_transport : strvar model_configvar protocol : Protocolvar requires_auth : boolvar timeout : float
Static methods
def validate_agent_uri(v: str) ‑> str-
Validate agent URI format.
def validate_auth_type(v: str) ‑> str-
Validate auth type.
def validate_mcp_transport(v: str) ‑> str-
Validate MCP transport type.
def validate_timeout(v: float) ‑> float-
Validate timeout is reasonable.
class AuthorizationContext (properties: list[dict[str, Any]])-
Expand source code
class AuthorizationContext: """Authorization context for a publisher domain. Attributes: property_ids: List of property IDs the agent is authorized for property_tags: List of property tags the agent is authorized for raw_properties: Raw property data from adagents.json """ def __init__(self, properties: list[dict[str, Any]]): """Initialize from list of properties. Args: properties: List of property dictionaries from adagents.json """ self.property_ids: list[str] = [] self.property_tags: list[str] = [] self.raw_properties = properties # Extract property IDs and tags for prop in properties: if not isinstance(prop, dict): continue # Extract property ID prop_id = prop.get("id") if prop_id and isinstance(prop_id, str): self.property_ids.append(prop_id) # Extract tags tags = prop.get("tags", []) if isinstance(tags, list): for tag in tags: if isinstance(tag, str) and tag not in self.property_tags: self.property_tags.append(tag) def __repr__(self) -> str: return ( f"AuthorizationContext(" f"property_ids={self.property_ids}, " f"property_tags={self.property_tags})" )Authorization context for a publisher domain.
Attributes
property_ids- List of property IDs the agent is authorized for
property_tags- List of property tags the agent is authorized for
raw_properties- Raw property data from adagents.json
Initialize from list of properties.
Args
properties- List of property dictionaries from adagents.json
class BrandManifest (**data: Any)-
Expand source code
class BrandManifest(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) assets: Annotated[ list[Asset] | None, Field( description='Brand asset library with explicit assets and tags. Assets are referenced inline with URLs pointing to CDN-hosted files.' ), ] = None colors: Annotated[Colors | None, Field(description='Brand color palette')] = None contact: Annotated[Contact | None, Field(description='Brand contact information')] = None disclaimers: Annotated[ list[Disclaimer] | None, Field(description='Legal disclaimers or required text that must appear in creatives'), ] = None fonts: Annotated[Fonts | None, Field(description='Brand typography guidelines')] = None industry: Annotated[ str | None, Field( description="Industry or vertical (e.g., 'retail', 'automotive', 'finance', 'healthcare')" ), ] = None logos: Annotated[ list[Logo] | None, Field(description='Brand logo assets with semantic tags for different use cases'), ] = None metadata: Annotated[Metadata | None, Field(description='Additional brand metadata')] = None name: Annotated[str, Field(description='Brand or business name')] product_catalog: Annotated[ ProductCatalog | None, Field( description='Product catalog information for e-commerce advertisers. Enables SKU-level creative generation and product selection.' ), ] = None tagline: Annotated[str | None, Field(description='Brand tagline or slogan')] = None target_audience: Annotated[ str | None, Field(description='Primary target audience description') ] = None tone: Annotated[ str | None, Field( description="Brand voice and messaging tone (e.g., 'professional', 'casual', 'humorous', 'trustworthy', 'innovative')" ), ] = None url: Annotated[ AnyUrl | None, Field( description='Primary brand URL for context and asset discovery. Creative agents can infer brand information from this URL.' ), ] = NoneBase model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var assets : list[Asset] | Nonevar colors : Colors | Nonevar contact : Contact | Nonevar disclaimers : list[Disclaimer] | Nonevar fonts : Fonts | Nonevar industry : str | Nonevar logos : list[Logo] | Nonevar metadata : Metadata | Nonevar model_configvar name : strvar product_catalog : ProductCatalog | Nonevar tagline : str | Nonevar target_audience : str | Nonevar tone : str | Nonevar url : pydantic.networks.AnyUrl | None
Inherited members
class BuildCreativeRequest (**data: Any)-
Expand source code
class BuildCreativeRequest(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context included in the request payload. Agentsmust echo this value back unchanged in responses and webhooks. Use for UI/session hints, correlation tokens, or tracking metadata.' ), ] = None creative_manifest: Annotated[ creative_manifest_1.CreativeManifest | None, Field( description='Creative manifest to transform or generate from. For pure generation, this should include the target format_id and any required input assets (e.g., promoted_offerings for generative formats). For transformation (e.g., resizing, reformatting), this is the complete creative to adapt.' ), ] = None message: Annotated[ str | None, Field( description='Natural language instructions for the transformation or generation. For pure generation, this is the creative brief. For transformation, this provides guidance on how to adapt the creative.' ), ] = None target_format_id: Annotated[ format_id.FormatId, Field( description='Format ID to generate. The format definition specifies required input assets and output structure.' ), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : dict[str, typing.Any] | Nonevar creative_manifest : CreativeManifest | Nonevar message : str | Nonevar model_configvar target_format_id : FormatId
Inherited members
class BuildCreativeResponse (root: RootModelRootType = PydanticUndefined, **data)-
Expand source code
class BuildCreativeResponse(RootModel[BuildCreativeResponse1 | BuildCreativeResponse2]): root: Annotated[ BuildCreativeResponse1 | BuildCreativeResponse2, Field( description='Response containing the transformed or generated creative manifest, ready for use with preview_creative or sync_creatives. Returns either the complete creative manifest OR error information, never both.', title='Build Creative Response', ), ]Usage Documentation
A Pydantic
BaseModelfor the root object of the model.Attributes
root- The root object of the model.
__pydantic_root_model__- Whether the model is a RootModel.
__pydantic_private__- Private fields in the model.
__pydantic_extra__- Extra fields in the model.
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- pydantic.root_model.RootModel[Union[BuildCreativeResponse1, BuildCreativeResponse2]]
- pydantic.root_model.RootModel
- pydantic.main.BaseModel
- typing.Generic
Class variables
var model_configvar root : BuildCreativeResponse1 | BuildCreativeResponse2
class BuildCreativeSuccessResponse (**data: Any)-
Expand source code
class BuildCreativeResponse1(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context echoed inside the task payload. Opaque metadata such as UI/session hints, correlation tokens, or tracking identifiers.' ), ] = None creative_manifest: Annotated[ creative_manifest_1.CreativeManifest, Field(description='The generated or transformed creative manifest'), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : dict[str, typing.Any] | Nonevar creative_manifest : CreativeManifestvar model_config
Inherited members
class BuildCreativeErrorResponse (**data: Any)-
Expand source code
class BuildCreativeResponse2(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context echoed inside the task payload. Opaque metadata such as UI/session hints, correlation tokens, or tracking identifiers.' ), ] = None errors: Annotated[ list[error.Error], Field( description='Array of errors explaining why creative generation failed', min_length=1 ), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : dict[str, typing.Any] | Nonevar errors : list[Error]var model_config
Inherited members
class CpcPricingOption (**data: Any)-
Expand source code
class CpcPricingOption(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) currency: Annotated[ str, Field( description='ISO 4217 currency code', examples=['USD', 'EUR', 'GBP', 'JPY'], pattern='^[A-Z]{3}$', ), ] is_fixed: Annotated[ Literal[True], Field(description='Whether this is a fixed rate (true) or auction-based (false)'), ] min_spend_per_package: Annotated[ float | None, Field( description='Minimum spend requirement per package using this pricing option, in the specified currency', ge=0.0, ), ] = None pricing_model: Annotated[Literal['cpc'], Field(description='Cost per click')] pricing_option_id: Annotated[ str, Field( description="Unique identifier for this pricing option within the product (e.g., 'cpc_usd_fixed')" ), ] rate: Annotated[float, Field(description='Fixed CPC rate (cost per click)', ge=0.0)]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var currency : strvar is_fixed : Literal[True]var min_spend_per_package : float | Nonevar model_configvar pricing_model : Literal['cpc']var pricing_option_id : strvar rate : float
Inherited members
class CpcvPricingOption (**data: Any)-
Expand source code
class CpcvPricingOption(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) currency: Annotated[ str, Field( description='ISO 4217 currency code', examples=['USD', 'EUR', 'GBP', 'JPY'], pattern='^[A-Z]{3}$', ), ] is_fixed: Annotated[ Literal[True], Field(description='Whether this is a fixed rate (true) or auction-based (false)'), ] min_spend_per_package: Annotated[ float | None, Field( description='Minimum spend requirement per package using this pricing option, in the specified currency', ge=0.0, ), ] = None pricing_model: Annotated[ Literal['cpcv'], Field(description='Cost per completed view (100% completion)') ] pricing_option_id: Annotated[ str, Field( description="Unique identifier for this pricing option within the product (e.g., 'cpcv_usd_guaranteed')" ), ] rate: Annotated[float, Field(description='Fixed CPCV rate (cost per 100% completion)', ge=0.0)]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var currency : strvar is_fixed : Literal[True]var min_spend_per_package : float | Nonevar model_configvar pricing_model : Literal['cpcv']var pricing_option_id : strvar rate : float
Inherited members
class CpmAuctionPricingOption (**data: Any)-
Expand source code
class CpmAuctionPricingOption(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) currency: Annotated[ str, Field( description='ISO 4217 currency code', examples=['USD', 'EUR', 'GBP', 'JPY'], pattern='^[A-Z]{3}$', ), ] is_fixed: Annotated[ Literal[False], Field(description='Whether this is a fixed rate (true) or auction-based (false)'), ] min_spend_per_package: Annotated[ float | None, Field( description='Minimum spend requirement per package using this pricing option, in the specified currency', ge=0.0, ), ] = None price_guidance: Annotated[ PriceGuidance, Field(description='Pricing guidance for auction-based CPM bidding') ] pricing_model: Annotated[Literal['cpm'], Field(description='Cost per 1,000 impressions')] pricing_option_id: Annotated[ str, Field( description="Unique identifier for this pricing option within the product (e.g., 'cpm_usd_auction')" ), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var currency : strvar is_fixed : Literal[False]var min_spend_per_package : float | Nonevar model_configvar price_guidance : PriceGuidancevar pricing_model : Literal['cpm']var pricing_option_id : str
Inherited members
class CpmFixedRatePricingOption (**data: Any)-
Expand source code
class CpmFixedRatePricingOption(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) currency: Annotated[ str, Field( description='ISO 4217 currency code', examples=['USD', 'EUR', 'GBP', 'JPY'], pattern='^[A-Z]{3}$', ), ] is_fixed: Annotated[ Literal[True], Field(description='Whether this is a fixed rate (true) or auction-based (false)'), ] min_spend_per_package: Annotated[ float | None, Field( description='Minimum spend requirement per package using this pricing option, in the specified currency', ge=0.0, ), ] = None pricing_model: Annotated[Literal['cpm'], Field(description='Cost per 1,000 impressions')] pricing_option_id: Annotated[ str, Field( description="Unique identifier for this pricing option within the product (e.g., 'cpm_usd_guaranteed')" ), ] rate: Annotated[float, Field(description='Fixed CPM rate (cost per 1,000 impressions)', ge=0.0)]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var currency : strvar is_fixed : Literal[True]var min_spend_per_package : float | Nonevar model_configvar pricing_model : Literal['cpm']var pricing_option_id : strvar rate : float
Inherited members
class CppPricingOption (**data: Any)-
Expand source code
class CppPricingOption(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) currency: Annotated[ str, Field( description='ISO 4217 currency code', examples=['USD', 'EUR', 'GBP', 'JPY'], pattern='^[A-Z]{3}$', ), ] is_fixed: Annotated[ Literal[True], Field(description='Whether this is a fixed rate (true) or auction-based (false)'), ] min_spend_per_package: Annotated[ float | None, Field( description='Minimum spend requirement per package using this pricing option, in the specified currency', ge=0.0, ), ] = None parameters: Annotated[ Parameters, Field(description='CPP-specific parameters for demographic targeting and GRP requirements'), ] pricing_model: Annotated[Literal['cpp'], Field(description='Cost per Gross Rating Point')] pricing_option_id: Annotated[ str, Field( description="Unique identifier for this pricing option within the product (e.g., 'cpp_usd_p18-49')" ), ] rate: Annotated[float, Field(description='Fixed CPP rate (cost per rating point)', ge=0.0)]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var currency : strvar is_fixed : Literal[True]var min_spend_per_package : float | Nonevar model_configvar parameters : Parametersvar pricing_model : Literal['cpp']var pricing_option_id : strvar rate : float
Inherited members
class CpvPricingOption (**data: Any)-
Expand source code
class CpvPricingOption(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) currency: Annotated[ str, Field( description='ISO 4217 currency code', examples=['USD', 'EUR', 'GBP', 'JPY'], pattern='^[A-Z]{3}$', ), ] is_fixed: Annotated[ Literal[True], Field(description='Whether this is a fixed rate (true) or auction-based (false)'), ] min_spend_per_package: Annotated[ float | None, Field( description='Minimum spend requirement per package using this pricing option, in the specified currency', ge=0.0, ), ] = None parameters: Annotated[ Parameters, Field(description='CPV-specific parameters defining the view threshold') ] pricing_model: Annotated[Literal['cpv'], Field(description='Cost per view at threshold')] pricing_option_id: Annotated[ str, Field( description="Unique identifier for this pricing option within the product (e.g., 'cpv_usd_50pct')" ), ] rate: Annotated[float, Field(description='Fixed CPV rate (cost per view)', ge=0.0)]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var currency : strvar is_fixed : Literal[True]var min_spend_per_package : float | Nonevar model_configvar parameters : Parametersvar pricing_model : Literal['cpv']var pricing_option_id : strvar rate : float
Inherited members
class CreateMediaBuyRequest (**data: Any)-
Expand source code
class CreateMediaBuyRequest(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) brand_manifest: Annotated[ brand_manifest_1.BrandManifest | AnyUrl, Field( description='Brand information manifest serving as the namespace and identity for this media buy. Provides brand context, assets, and product catalog. Can be provided inline or as a URL reference to a hosted manifest. Can be cached and reused across multiple requests.', examples=[ { 'data': { 'colors': {'primary': '#FF6B35'}, 'name': 'ACME Corporation', 'url': 'https://acmecorp.com', }, 'description': 'Inline brand manifest', }, { 'data': 'https://cdn.acmecorp.com/brand-manifest.json', 'description': 'URL string reference to hosted manifest', }, ], title='Brand Manifest Reference', ), ] buyer_ref: Annotated[str, Field(description="Buyer's reference identifier for this media buy")] context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context included in the request payload. Agentsmust echo this value back unchanged in responses and webhooks. Use for UI/session hints, correlation tokens, or tracking metadata.' ), ] = None end_time: Annotated[ AwareDatetime, Field(description='Campaign end date/time in ISO 8601 format') ] packages: Annotated[ list[package_request.PackageRequest], Field(description='Array of package configurations') ] po_number: Annotated[str | None, Field(description='Purchase order number for tracking')] = None reporting_webhook: ReportingWebhook | None = None start_time: Annotated[ str | AwareDatetime, Field( description="Campaign start timing: 'asap' or ISO 8601 date-time", title='Start Timing' ), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var brand_manifest : BrandManifest | pydantic.networks.AnyUrlvar buyer_ref : strvar context : dict[str, typing.Any] | Nonevar end_time : pydantic.types.AwareDatetimevar model_configvar packages : list[PackageRequest]var po_number : str | Nonevar reporting_webhook : ReportingWebhook | Nonevar start_time : str | pydantic.types.AwareDatetime
Inherited members
class CreateMediaBuyResponse (root: RootModelRootType = PydanticUndefined, **data)-
Expand source code
class CreateMediaBuyResponse(RootModel[CreateMediaBuyResponse1 | CreateMediaBuyResponse2]): root: Annotated[ CreateMediaBuyResponse1 | CreateMediaBuyResponse2, Field( description='Response payload for create_media_buy task. Returns either complete success data OR error information, never both. This enforces atomic operation semantics - the media buy is either fully created or not created at all.', title='Create Media Buy Response', ), ]Usage Documentation
A Pydantic
BaseModelfor the root object of the model.Attributes
root- The root object of the model.
__pydantic_root_model__- Whether the model is a RootModel.
__pydantic_private__- Private fields in the model.
__pydantic_extra__- Extra fields in the model.
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- pydantic.root_model.RootModel[Union[CreateMediaBuyResponse1, CreateMediaBuyResponse2]]
- pydantic.root_model.RootModel
- pydantic.main.BaseModel
- typing.Generic
Class variables
var model_configvar root : CreateMediaBuyResponse1 | CreateMediaBuyResponse2
class CreateMediaBuySuccessResponse (**data: Any)-
Expand source code
class CreateMediaBuyResponse1(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) buyer_ref: Annotated[str, Field(description="Buyer's reference identifier for this media buy")] context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context echoed inside the task payload. Opaque metadata such as UI/session hints, correlation tokens, or tracking identifiers.' ), ] = None creative_deadline: Annotated[ AwareDatetime | None, Field(description='ISO 8601 timestamp for creative upload deadline') ] = None media_buy_id: Annotated[ str, Field(description="Publisher's unique identifier for the created media buy") ] packages: Annotated[list[Package], Field(description='Array of created packages')]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var buyer_ref : strvar context : dict[str, typing.Any] | Nonevar creative_deadline : pydantic.types.AwareDatetime | Nonevar media_buy_id : strvar model_configvar packages : list[Package]
Inherited members
class CreateMediaBuyErrorResponse (**data: Any)-
Expand source code
class CreateMediaBuyResponse2(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context echoed inside the task payload. Opaque metadata such as UI/session hints, correlation tokens, or tracking identifiers.' ), ] = None errors: Annotated[ list[error.Error], Field(description='Array of errors explaining why the operation failed', min_length=1), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : dict[str, typing.Any] | Nonevar errors : list[Error]var model_config
Inherited members
class Creative (**data: Any)-
Expand source code
class Creative(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) assets: Annotated[ dict[ str, image_asset.ImageAsset | video_asset.VideoAsset | audio_asset.AudioAsset | text_asset.TextAsset | html_asset.HtmlAsset | css_asset.CssAsset | javascript_asset.JavascriptAsset | promoted_offerings.PromotedOfferings | url_asset.UrlAsset | vast_asset.VastAsset1 | vast_asset.VastAsset2 | daast_asset.DaastAsset1 | daast_asset.DaastAsset2, ] | None, Field(description='Assets for this creative, keyed by asset_role'), ] = None assignments: Annotated[ Assignments | None, Field(description='Current package assignments (included when include_assignments=true)'), ] = None created_date: Annotated[ AwareDatetime, Field(description='When the creative was uploaded to the library') ] creative_id: Annotated[str, Field(description='Unique identifier for the creative')] format_id: Annotated[ format_id_1.FormatId, Field(description='Format identifier specifying which format this creative conforms to'), ] name: Annotated[str, Field(description='Human-readable creative name')] performance: Annotated[ Performance | None, Field( description='Aggregated performance metrics (included when include_performance=true)' ), ] = None status: Annotated[ creative_status.CreativeStatus, Field(description='Current approval status of the creative') ] sub_assets: Annotated[ list[sub_asset.SubAsset1 | sub_asset.SubAsset2] | None, Field( description='Sub-assets for multi-asset formats (included when include_sub_assets=true)' ), ] = None tags: Annotated[ list[str] | None, Field(description='User-defined tags for organization and searchability') ] = None updated_date: Annotated[AwareDatetime, Field(description='When the creative was last modified')]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var assets : dict[str, ImageAsset | VideoAsset | AudioAsset | TextAsset | HtmlAsset | CssAsset | JavascriptAsset | PromotedOfferings | UrlAsset | VastAsset1 | VastAsset2 | DaastAsset1 | DaastAsset2] | Nonevar assignments : Assignments | Nonevar created_date : pydantic.types.AwareDatetimevar creative_id : strvar format_id : FormatIdvar model_configvar name : strvar performance : Performance | Nonevar status : CreativeStatusvar sub_assets : list[SubAsset1 | SubAsset2] | Nonevar updated_date : pydantic.types.AwareDatetime
Inherited members
class CreativeManifest (**data: Any)-
Expand source code
class CreativeManifest(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) assets: Annotated[ dict[ str, image_asset.ImageAsset | video_asset.VideoAsset | audio_asset.AudioAsset | text_asset.TextAsset | url_asset.UrlAsset | html_asset.HtmlAsset | javascript_asset.JavascriptAsset | webhook_asset.WebhookAsset | css_asset.CssAsset | promoted_offerings.PromotedOfferings | vast_asset.VastAsset1 | vast_asset.VastAsset2 | daast_asset.DaastAsset1 | daast_asset.DaastAsset2, ], Field( description="Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets_required array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nIMPORTANT: Creative manifest validation MUST be performed in the context of the format specification. The format defines what type each asset_id should be, which eliminates any validation ambiguity." ), ] format_id: Annotated[ format_id_1.FormatId, Field(description='Format identifier this manifest is for') ] promoted_offering: Annotated[ str | None, Field( description='Product name or offering being advertised. Maps to promoted_offerings in create_media_buy request to associate creative with the product being promoted.' ), ] = NoneBase model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var assets : dict[str, ImageAsset | VideoAsset | AudioAsset | TextAsset | UrlAsset | HtmlAsset | JavascriptAsset | WebhookAsset | CssAsset | PromotedOfferings | VastAsset1 | VastAsset2 | DaastAsset1 | DaastAsset2]var format_id : FormatIdvar model_configvar promoted_offering : str | None
Inherited members
class CreativeStatus (*args, **kwds)-
Expand source code
class CreativeStatus(Enum): processing = 'processing' approved = 'approved' rejected = 'rejected' pending_review = 'pending_review'Create a collection of name/value pairs.
Example enumeration:
>>> class Color(Enum): ... RED = 1 ... BLUE = 2 ... GREEN = 3Access them by:
- attribute access::
>>> Color.RED <Color.RED: 1>- value lookup:
>>> Color(1) <Color.RED: 1>- name lookup:
>>> Color['RED'] <Color.RED: 1>Enumerations can be iterated over, and know how many members they have:
>>> len(Color) 3>>> list(Color) [<Color.RED: 1>, <Color.BLUE: 2>, <Color.GREEN: 3>]Methods can be added to enumerations, and members can have their own attributes – see the documentation for details.
Ancestors
- enum.Enum
Class variables
var approvedvar pending_reviewvar processingvar rejected
class UrlDaastAsset (**data: Any)-
Expand source code
class DaastAsset1(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) companion_ads: Annotated[ bool | None, Field(description='Whether companion display ads are included') ] = None daast_version: Annotated[ DaastVersion | None, Field(description='DAAST specification version') ] = None delivery_type: Annotated[ Literal['url'], Field(description='Discriminator indicating DAAST is delivered via URL endpoint'), ] duration_ms: Annotated[ int | None, Field(description='Expected audio duration in milliseconds (if known)', ge=0) ] = None tracking_events: Annotated[ list[TrackingEvent] | None, Field(description='Tracking events supported by this DAAST tag') ] = None url: Annotated[AnyUrl, Field(description='URL endpoint that returns DAAST XML')]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var companion_ads : bool | Nonevar daast_version : DaastVersion | Nonevar delivery_type : Literal['url']var duration_ms : int | Nonevar model_configvar tracking_events : list[TrackingEvent] | Nonevar url : pydantic.networks.AnyUrl
Inherited members
class InlineDaastAsset (**data: Any)-
Expand source code
class DaastAsset2(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) companion_ads: Annotated[ bool | None, Field(description='Whether companion display ads are included') ] = None content: Annotated[str, Field(description='Inline DAAST XML content')] daast_version: Annotated[ DaastVersion | None, Field(description='DAAST specification version') ] = None delivery_type: Annotated[ Literal['inline'], Field(description='Discriminator indicating DAAST is delivered as inline XML content'), ] duration_ms: Annotated[ int | None, Field(description='Expected audio duration in milliseconds (if known)', ge=0) ] = None tracking_events: Annotated[ list[TrackingEvent] | None, Field(description='Tracking events supported by this DAAST tag') ] = NoneBase model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var companion_ads : bool | Nonevar content : strvar daast_version : DaastVersion | Nonevar delivery_type : Literal['inline']var duration_ms : int | Nonevar model_configvar tracking_events : list[TrackingEvent] | None
Inherited members
class PlatformDeployment (**data: Any)-
Expand source code
class Deployment1(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) account: Annotated[str | None, Field(description='Account identifier if applicable')] = None activation_key: Annotated[ activation_key_1.ActivationKey1 | activation_key_1.ActivationKey2 | None, Field( description='The key to use for targeting. Only present if is_live=true AND requester has access to this destination.', title='Activation Key', ), ] = None deployed_at: Annotated[ AwareDatetime | None, Field(description='Timestamp when activation completed (if is_live=true)'), ] = None estimated_activation_duration_minutes: Annotated[ float | None, Field( description='Estimated time to activate if not live, or to complete activation if in progress', ge=0.0, ), ] = None is_live: Annotated[ bool, Field(description='Whether signal is currently active on this destination') ] platform: Annotated[str, Field(description='Platform identifier for DSPs')] type: Annotated[ Literal['platform'], Field(description='Discriminator indicating this is a platform-based deployment'), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var account : str | Nonevar activation_key : ActivationKey1 | ActivationKey2 | Nonevar deployed_at : pydantic.types.AwareDatetime | Nonevar estimated_activation_duration_minutes : float | Nonevar is_live : boolvar model_configvar platform : strvar type : Literal['platform']
Inherited members
class AgentDeployment (**data: Any)-
Expand source code
class Deployment2(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) account: Annotated[str | None, Field(description='Account identifier if applicable')] = None activation_key: Annotated[ activation_key_1.ActivationKey1 | activation_key_1.ActivationKey2 | None, Field( description='The key to use for targeting. Only present if is_live=true AND requester has access to this destination.', title='Activation Key', ), ] = None agent_url: Annotated[AnyUrl, Field(description='URL identifying the destination agent')] deployed_at: Annotated[ AwareDatetime | None, Field(description='Timestamp when activation completed (if is_live=true)'), ] = None estimated_activation_duration_minutes: Annotated[ float | None, Field( description='Estimated time to activate if not live, or to complete activation if in progress', ge=0.0, ), ] = None is_live: Annotated[ bool, Field(description='Whether signal is currently active on this destination') ] type: Annotated[ Literal['agent'], Field(description='Discriminator indicating this is an agent URL-based deployment'), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var account : str | Nonevar activation_key : ActivationKey1 | ActivationKey2 | Nonevar agent_url : pydantic.networks.AnyUrlvar deployed_at : pydantic.types.AwareDatetime | Nonevar estimated_activation_duration_minutes : float | Nonevar is_live : boolvar model_configvar type : Literal['agent']
Inherited members
class PlatformDestination (**data: Any)-
Expand source code
class Destination1(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) account: Annotated[ str | None, Field(description='Optional account identifier on the platform') ] = None platform: Annotated[ str, Field(description="Platform identifier for DSPs (e.g., 'the-trade-desk', 'amazon-dsp')"), ] type: Annotated[ Literal['platform'], Field(description='Discriminator indicating this is a platform-based destination'), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var account : str | Nonevar model_configvar platform : strvar type : Literal['platform']
Inherited members
class AgentDestination (**data: Any)-
Expand source code
class Destination2(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) account: Annotated[ str | None, Field(description='Optional account identifier on the agent') ] = None agent_url: Annotated[ AnyUrl, Field(description='URL identifying the destination agent (for sales agents, etc.)') ] type: Annotated[ Literal['agent'], Field(description='Discriminator indicating this is an agent URL-based destination'), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var account : str | Nonevar agent_url : pydantic.networks.AnyUrlvar model_configvar type : Literal['agent']
Inherited members
class Error (**data: Any)-
Expand source code
class Error(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) code: Annotated[str, Field(description='Error code for programmatic handling')] details: Annotated[Any | None, Field(description='Additional task-specific error details')] = ( None ) field: Annotated[ str | None, Field(description="Field path associated with the error (e.g., 'packages[0].targeting')"), ] = None message: Annotated[str, Field(description='Human-readable error message')] retry_after: Annotated[ float | None, Field(description='Seconds to wait before retrying the operation', ge=0.0) ] = None suggestion: Annotated[str | None, Field(description='Suggested fix for the error')] = NoneBase model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var code : strvar details : typing.Any | Nonevar field : str | Nonevar message : strvar model_configvar retry_after : float | Nonevar suggestion : str | None
Inherited members
class FlatRatePricingOption (**data: Any)-
Expand source code
class FlatRatePricingOption(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) currency: Annotated[ str, Field( description='ISO 4217 currency code', examples=['USD', 'EUR', 'GBP', 'JPY'], pattern='^[A-Z]{3}$', ), ] is_fixed: Annotated[ Literal[True], Field(description='Whether this is a fixed rate (true) or auction-based (false)'), ] min_spend_per_package: Annotated[ float | None, Field( description='Minimum spend requirement per package using this pricing option, in the specified currency', ge=0.0, ), ] = None parameters: Annotated[ Parameters | None, Field(description='Flat rate parameters for DOOH and time-based campaigns'), ] = None pricing_model: Annotated[ Literal['flat_rate'], Field(description='Fixed cost regardless of delivery volume') ] pricing_option_id: Annotated[ str, Field( description="Unique identifier for this pricing option within the product (e.g., 'flat_rate_usd_24h_takeover')" ), ] rate: Annotated[float, Field(description='Flat rate cost', ge=0.0)]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var currency : strvar is_fixed : Literal[True]var min_spend_per_package : float | Nonevar model_configvar parameters : Parameters | Nonevar pricing_model : Literal['flat_rate']var pricing_option_id : strvar rate : float
Inherited members
class Format (**data: Any)-
Expand source code
class Format(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) assets_required: Annotated[ list[AssetsRequired | AssetsRequired1] | None, Field( description='Array of required assets or asset groups for this format. Each asset is identified by its asset_id, which must be used as the key in creative manifests. Can contain individual assets or repeatable asset sequences (e.g., carousel products, slideshow frames).' ), ] = None delivery: Annotated[ dict[str, Any] | None, Field(description='Delivery method specifications (e.g., hosted, VAST, third-party tags)'), ] = None description: Annotated[ str | None, Field( description='Plain text explanation of what this format does and what assets it requires' ), ] = None example_url: Annotated[ AnyUrl | None, Field( description='Optional URL to showcase page with examples and interactive demos of this format' ), ] = None format_card: Annotated[ FormatCard | None, Field( description='Optional standard visual card (300x400px) for displaying this format in user interfaces. Can be rendered via preview_creative or pre-generated.' ), ] = None format_card_detailed: Annotated[ FormatCardDetailed | None, Field( description='Optional detailed card with carousel and full specifications. Provides rich format documentation similar to ad spec pages.' ), ] = None format_id: Annotated[ format_id_1.FormatId, Field(description='Structured format identifier with agent URL and format name'), ] name: Annotated[str, Field(description='Human-readable format name')] output_format_ids: Annotated[ list[format_id_1.FormatId] | None, Field( description='For generative formats: array of format IDs that this format can generate. When a format accepts inputs like brand_manifest and message, this specifies what concrete output formats can be produced (e.g., a generative banner format might output standard image banner formats).' ), ] = None preview_image: Annotated[ AnyUrl | None, Field( description='DEPRECATED: Use format_card instead. Optional preview image URL for format browsing/discovery UI. Should be 400x300px (4:3 aspect ratio) PNG or JPG. Used as thumbnail/card image in format browsers. This field is maintained for backward compatibility but format_card provides a more flexible, structured approach.' ), ] = None renders: Annotated[ list[Render] | None, Field( description='Specification of rendered pieces for this format. Most formats produce a single render. Companion ad formats (video + banner), adaptive formats, and multi-placement formats produce multiple renders. Each render specifies its role and dimensions.', min_length=1, ), ] = None supported_macros: Annotated[ list[str] | None, Field( description='List of universal macros supported by this format (e.g., MEDIA_BUY_ID, CACHEBUSTER, DEVICE_ID). Used for validation and developer tooling.' ), ] = None type: Annotated[ Type, Field( description='Media type of this format - determines rendering method and asset requirements' ), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var assets_required : list[AssetsRequired | AssetsRequired1] | Nonevar delivery : dict[str, typing.Any] | Nonevar description : str | Nonevar example_url : pydantic.networks.AnyUrl | Nonevar format_card : FormatCard | Nonevar format_card_detailed : FormatCardDetailed | Nonevar format_id : FormatIdvar model_configvar name : strvar output_format_ids : list[FormatId] | Nonevar preview_image : pydantic.networks.AnyUrl | Nonevar renders : list[Render] | Nonevar supported_macros : list[str] | Nonevar type : Type
Inherited members
class FormatId (**data: Any)-
Expand source code
class FormatId(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) agent_url: Annotated[ AnyUrl, Field( description="URL of the agent that defines this format (e.g., 'https://creatives.adcontextprotocol.org' for standard formats, or 'https://publisher.com/.well-known/adcp/sales' for custom formats)" ), ] id: Annotated[ str, Field( description="Format identifier within the agent's namespace (e.g., 'display_300x250', 'video_standard_30s')", pattern='^[a-zA-Z0-9_-]+$', ), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var agent_url : pydantic.networks.AnyUrlvar id : strvar model_config
Inherited members
class GetMediaBuyDeliveryRequest (**data: Any)-
Expand source code
class GetMediaBuyDeliveryRequest(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) buyer_refs: Annotated[ list[str] | None, Field(description='Array of buyer reference IDs to get delivery data for') ] = None context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context included in the request payload. Agentsmust echo this value back unchanged in responses and webhooks. Use for UI/session hints, correlation tokens, or tracking metadata.' ), ] = None end_date: Annotated[ str | None, Field( description='End date for reporting period (YYYY-MM-DD)', pattern='^\\d{4}-\\d{2}-\\d{2}$', ), ] = None media_buy_ids: Annotated[ list[str] | None, Field(description='Array of publisher media buy IDs to get delivery data for'), ] = None start_date: Annotated[ str | None, Field( description='Start date for reporting period (YYYY-MM-DD)', pattern='^\\d{4}-\\d{2}-\\d{2}$', ), ] = None status_filter: Annotated[ StatusFilter | list[StatusFilterEnum] | None, Field(description='Filter by status. Can be a single status or array of statuses'), ] = NoneBase model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var buyer_refs : list[str] | Nonevar context : dict[str, typing.Any] | Nonevar end_date : str | Nonevar media_buy_ids : list[str] | Nonevar model_configvar start_date : str | Nonevar status_filter : StatusFilter | list[StatusFilterEnum] | None
Inherited members
class GetMediaBuyDeliveryResponse (**data: Any)-
Expand source code
class GetMediaBuyDeliveryResponse(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) aggregated_totals: Annotated[ AggregatedTotals | None, Field( description='Combined metrics across all returned media buys. Only included in API responses (get_media_buy_delivery), not in webhook notifications.' ), ] = None context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context echoed inside the task payload. Opaque metadata such as UI/session hints, correlation tokens, or tracking identifiers.' ), ] = None currency: Annotated[str, Field(description='ISO 4217 currency code', pattern='^[A-Z]{3}$')] errors: Annotated[ list[error.Error] | None, Field( description='Task-specific errors and warnings (e.g., missing delivery data, reporting platform issues)' ), ] = None media_buy_deliveries: Annotated[ list[MediaBuyDelivery], Field( description='Array of delivery data for media buys. When used in webhook notifications, may contain multiple media buys aggregated by publisher. When used in get_media_buy_delivery API responses, typically contains requested media buys.' ), ] next_expected_at: Annotated[ AwareDatetime | None, Field( description="ISO 8601 timestamp for next expected notification (only present in webhook deliveries when notification_type is not 'final')" ), ] = None notification_type: Annotated[ NotificationType | None, Field( description='Type of webhook notification (only present in webhook deliveries): scheduled = regular periodic update, final = campaign completed, delayed = data not yet available, adjusted = resending period with updated data' ), ] = None partial_data: Annotated[ bool | None, Field( description='Indicates if any media buys in this webhook have missing/delayed data (only present in webhook deliveries)' ), ] = None reporting_period: Annotated[ ReportingPeriod, Field(description='Date range for the report. All periods use UTC timezone.'), ] sequence_number: Annotated[ int | None, Field( description='Sequential notification number (only present in webhook deliveries, starts at 1)', ge=1, ), ] = None unavailable_count: Annotated[ int | None, Field( description='Number of media buys with reporting_delayed or failed status (only present in webhook deliveries when partial_data is true)', ge=0, ), ] = NoneBase model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var aggregated_totals : AggregatedTotals | Nonevar context : dict[str, typing.Any] | Nonevar currency : strvar errors : list[Error] | Nonevar media_buy_deliveries : list[MediaBuyDelivery]var model_configvar next_expected_at : pydantic.types.AwareDatetime | Nonevar notification_type : NotificationType | Nonevar partial_data : bool | Nonevar reporting_period : ReportingPeriodvar sequence_number : int | None
Inherited members
class GetProductsRequest (**data: Any)-
Expand source code
class GetProductsRequest(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) brand_manifest: Annotated[ brand_manifest_1.BrandManifest | AnyUrl | None, Field( description='Brand information manifest providing brand context, assets, and product catalog. Can be provided inline or as a URL reference to a hosted manifest.', examples=[ { 'data': { 'colors': {'primary': '#FF6B35'}, 'name': 'ACME Corporation', 'url': 'https://acmecorp.com', }, 'description': 'Inline brand manifest', }, { 'data': 'https://cdn.acmecorp.com/brand-manifest.json', 'description': 'URL string reference to hosted manifest', }, ], title='Brand Manifest Reference', ), ] = None brief: Annotated[ str | None, Field(description='Natural language description of campaign requirements') ] = None context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context included in the request payload. Agentsmust echo this value back unchanged in responses and webhooks. Use for UI/session hints, correlation tokens, or tracking metadata.' ), ] = None filters: Annotated[ Filters | None, Field(description='Structured filters for product discovery') ] = NoneBase model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var brand_manifest : BrandManifest | pydantic.networks.AnyUrl | Nonevar brief : str | Nonevar context : dict[str, typing.Any] | Nonevar filters : Filters | Nonevar model_config
Inherited members
class GetProductsResponse (**data: Any)-
Expand source code
class GetProductsResponse(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context echoed inside the task payload. Opaque metadata such as UI/session hints, correlation tokens, or tracking identifiers.' ), ] = None errors: Annotated[ list[error.Error] | None, Field(description='Task-specific errors and warnings (e.g., product filtering issues)'), ] = None products: Annotated[list[product.Product], Field(description='Array of matching products')]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : dict[str, typing.Any] | Nonevar errors : list[Error] | Nonevar model_configvar products : list[Product]
Inherited members
class GetSignalsRequest (**data: Any)-
Expand source code
class GetSignalsRequest(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context included in the request payload. Agents must echo this value back unchanged in responses and webhooks. Use for UI/session hints, correlation tokens, or tracking metadata.' ), ] = None deliver_to: Annotated[ DeliverTo, Field(description='Destination platforms where signals need to be activated') ] filters: Annotated[Filters | None, Field(description='Filters to refine results')] = None max_results: Annotated[ int | None, Field(description='Maximum number of results to return', ge=1) ] = None signal_spec: Annotated[ str, Field(description='Natural language description of the desired signals') ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : dict[str, typing.Any] | Nonevar deliver_to : DeliverTovar filters : Filters | Nonevar max_results : int | Nonevar model_configvar signal_spec : str
Inherited members
class GetSignalsResponse (**data: Any)-
Expand source code
class GetSignalsResponse(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context echoed inside the task payload. Opaque metadata such as UI/session hints, correlation tokens, or tracking identifiers.' ), ] = None errors: Annotated[ list[error.Error] | None, Field( description='Task-specific errors and warnings (e.g., signal discovery or pricing issues)' ), ] = None signals: Annotated[list[Signal], Field(description='Array of matching signals')]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : dict[str, typing.Any] | Nonevar errors : list[Error] | Nonevar model_configvar signals : list[Signal]
Inherited members
class ListAuthorizedPropertiesRequest (**data: Any)-
Expand source code
class ListAuthorizedPropertiesRequest(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context included in the request payload. Agentsmust echo this value back unchanged in responses and webhooks. Use for UI/session hints, correlation tokens, or tracking metadata.' ), ] = None publisher_domains: Annotated[ list[PublisherDomain] | None, Field( description='Filter to specific publisher domains (optional). If omitted, returns all publishers this agent represents.', min_length=1, ), ] = NoneBase model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : dict[str, typing.Any] | Nonevar model_configvar publisher_domains : list[PublisherDomain] | None
Inherited members
class ListAuthorizedPropertiesResponse (**data: Any)-
Expand source code
class ListAuthorizedPropertiesResponse(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) advertising_policies: Annotated[ str | None, Field( description="Publisher's advertising content policies, restrictions, and guidelines in natural language. May include prohibited categories, blocked advertisers, restricted tactics, brand safety requirements, or links to full policy documentation.", max_length=10000, min_length=1, ), ] = None context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context echoed inside the task payload. Opaque metadata such as UI/session hints, correlation tokens, or tracking identifiers.' ), ] = None errors: Annotated[ list[error.Error] | None, Field(description='Task-specific errors and warnings (e.g., property availability issues)'), ] = None last_updated: Annotated[ AwareDatetime | None, Field( description="ISO 8601 timestamp of when the agent's publisher authorization list was last updated. Buyers can use this to determine if their cached publisher adagents.json files might be stale." ), ] = None portfolio_description: Annotated[ str | None, Field( description='Markdown-formatted description of the property portfolio, including inventory types, audience characteristics, and special features.', max_length=5000, min_length=1, ), ] = None primary_channels: Annotated[ list[channels.AdvertisingChannels] | None, Field( description='Primary advertising channels represented in this property portfolio. Helps buying agents quickly filter relevance.', min_length=1, ), ] = None primary_countries: Annotated[ list[PrimaryCountry] | None, Field( description='Primary countries (ISO 3166-1 alpha-2 codes) where properties are concentrated. Helps buying agents quickly filter relevance.', min_length=1, ), ] = None publisher_domains: Annotated[ list[PublisherDomain], Field( description="Publisher domains this agent is authorized to represent. Buyers should fetch each publisher's adagents.json to see property definitions and verify this agent is in their authorized_agents list with authorization scope.", min_length=1, ), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var advertising_policies : str | Nonevar context : dict[str, typing.Any] | Nonevar errors : list[Error] | Nonevar last_updated : pydantic.types.AwareDatetime | Nonevar model_configvar portfolio_description : str | Nonevar primary_channels : list[AdvertisingChannels] | Nonevar primary_countries : list[PrimaryCountry] | Nonevar publisher_domains : list[PublisherDomain]
Inherited members
class ListCreativeFormatsRequest (**data: Any)-
Expand source code
class ListCreativeFormatsRequest(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) asset_types: Annotated[ list[AssetType] | None, Field( description="Filter to formats that include these asset types. For third-party tags, search for 'html' or 'javascript'. E.g., ['image', 'text'] returns formats with images and text, ['javascript'] returns formats accepting JavaScript tags." ), ] = None context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context included in the request payload. Agents must echo this value back unchanged in responses and webhooks. Use for UI/session hints, correlation tokens, or tracking metadata.' ), ] = None format_ids: Annotated[ list[format_id.FormatId] | None, Field( description='Return only these specific format IDs (e.g., from get_products response)' ), ] = None is_responsive: Annotated[ bool | None, Field( description='Filter for responsive formats that adapt to container size. When true, returns formats without fixed dimensions.' ), ] = None max_height: Annotated[ int | None, Field( description='Maximum height in pixels (inclusive). Returns formats where ANY render has height <= this value. For multi-render formats, matches if at least one render fits.' ), ] = None max_width: Annotated[ int | None, Field( description='Maximum width in pixels (inclusive). Returns formats where ANY render has width <= this value. For multi-render formats, matches if at least one render fits.' ), ] = None min_height: Annotated[ int | None, Field( description='Minimum height in pixels (inclusive). Returns formats where ANY render has height >= this value.' ), ] = None min_width: Annotated[ int | None, Field( description='Minimum width in pixels (inclusive). Returns formats where ANY render has width >= this value.' ), ] = None name_search: Annotated[ str | None, Field(description='Search for formats by name (case-insensitive partial match)') ] = None type: Annotated[ Type | None, Field( description='Filter by format type (technical categories with distinct requirements)' ), ] = NoneBase model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var asset_types : list[AssetType] | Nonevar context : dict[str, typing.Any] | Nonevar format_ids : list[FormatId] | Nonevar is_responsive : bool | Nonevar max_height : int | Nonevar max_width : int | Nonevar min_height : int | Nonevar min_width : int | Nonevar model_configvar name_search : str | Nonevar type : Type | None
Inherited members
class ListCreativeFormatsResponse (**data: Any)-
Expand source code
class ListCreativeFormatsResponse(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context echoed inside the task payload. Opaque metadata such as UI/session hints, correlation tokens, or tracking identifiers.' ), ] = None creative_agents: Annotated[ list[CreativeAgent] | None, Field( description='Optional: Creative agents that provide additional formats. Buyers can recursively query these agents to discover more formats. No authentication required for list_creative_formats.' ), ] = None errors: Annotated[ list[error.Error] | None, Field(description='Task-specific errors and warnings (e.g., format availability issues)'), ] = None formats: Annotated[ list[format.Format], Field( description="Full format definitions for all formats this agent supports. Each format's authoritative source is indicated by its agent_url field." ), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : dict[str, typing.Any] | Nonevar creative_agents : list[CreativeAgent] | Nonevar errors : list[Error] | Nonevar formats : list[Format]var model_config
Inherited members
class ListCreativesRequest (**data: Any)-
Expand source code
class ListCreativesRequest(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context included in the request payload. Agentsmust echo this value back unchanged in responses and webhooks. Use for UI/session hints, correlation tokens, or tracking metadata.' ), ] = None fields: Annotated[ list[FieldModel] | None, Field(description='Specific fields to include in response (omit for all fields)'), ] = None filters: Annotated[ Filters | None, Field(description='Filter criteria for querying creatives') ] = None include_assignments: Annotated[ bool | None, Field(description='Include package assignment information in response') ] = True include_performance: Annotated[ bool | None, Field(description='Include aggregated performance metrics in response') ] = False include_sub_assets: Annotated[ bool | None, Field(description='Include sub-assets (for carousel/native formats) in response'), ] = False pagination: Annotated[Pagination | None, Field(description='Pagination parameters')] = None sort: Annotated[Sort | None, Field(description='Sorting parameters')] = NoneBase model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : dict[str, typing.Any] | Nonevar fields : list[FieldModel] | Nonevar filters : Filters | Nonevar include_assignments : bool | Nonevar include_performance : bool | Nonevar include_sub_assets : bool | Nonevar model_configvar pagination : Pagination | Nonevar sort : Sort | None
Inherited members
class ListCreativesResponse (**data: Any)-
Expand source code
class ListCreativesResponse(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context echoed inside the task payload. Opaque metadata such as UI/session hints, correlation tokens, or tracking identifiers.' ), ] = None creatives: Annotated[ list[Creative], Field(description='Array of creative assets matching the query') ] format_summary: Annotated[ dict[str, int] | None, Field(description='Breakdown of creatives by format type') ] = None pagination: Annotated[ Pagination, Field(description='Pagination information for navigating results') ] query_summary: Annotated[ QuerySummary, Field(description='Summary of the query that was executed') ] status_summary: Annotated[ StatusSummary | None, Field(description='Breakdown of creatives by status') ] = NoneBase model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : dict[str, typing.Any] | Nonevar creatives : list[Creative]var format_summary : dict[str, int] | Nonevar model_configvar pagination : Paginationvar query_summary : QuerySummaryvar status_summary : StatusSummary | None
Inherited members
class MediaBuy (**data: Any)-
Expand source code
class MediaBuy(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) buyer_ref: Annotated[ str | None, Field(description="Buyer's reference identifier for this media buy") ] = None created_at: Annotated[AwareDatetime | None, Field(description='Creation timestamp')] = None creative_deadline: Annotated[ AwareDatetime | None, Field(description='ISO 8601 timestamp for creative upload deadline') ] = None media_buy_id: Annotated[ str, Field(description="Publisher's unique identifier for the media buy") ] packages: Annotated[ list[package.Package], Field(description='Array of packages within this media buy') ] promoted_offering: Annotated[ str, Field(description='Description of advertiser and what is being promoted') ] status: media_buy_status.MediaBuyStatus total_budget: Annotated[float, Field(description='Total budget amount', ge=0.0)] updated_at: Annotated[AwareDatetime | None, Field(description='Last update timestamp')] = NoneBase model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var buyer_ref : str | Nonevar created_at : pydantic.types.AwareDatetime | Nonevar creative_deadline : pydantic.types.AwareDatetime | Nonevar media_buy_id : strvar model_configvar packages : list[Package]var promoted_offering : strvar status : MediaBuyStatusvar total_budget : floatvar updated_at : pydantic.types.AwareDatetime | None
Inherited members
class MediaBuyStatus (*args, **kwds)-
Expand source code
class MediaBuyStatus(Enum): pending_activation = 'pending_activation' active = 'active' paused = 'paused' completed = 'completed'Create a collection of name/value pairs.
Example enumeration:
>>> class Color(Enum): ... RED = 1 ... BLUE = 2 ... GREEN = 3Access them by:
- attribute access::
>>> Color.RED <Color.RED: 1>- value lookup:
>>> Color(1) <Color.RED: 1>- name lookup:
>>> Color['RED'] <Color.RED: 1>Enumerations can be iterated over, and know how many members they have:
>>> len(Color) 3>>> list(Color) [<Color.RED: 1>, <Color.BLUE: 2>, <Color.GREEN: 3>]Methods can be added to enumerations, and members can have their own attributes – see the documentation for details.
Ancestors
- enum.Enum
Class variables
var activevar completedvar pausedvar pending_activation
class Package (**data: Any)-
Expand source code
class Package(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) bid_price: Annotated[ float | None, Field( description='Bid price for auction-based CPM pricing (present if using cpm-auction-option)', ge=0.0, ), ] = None budget: Annotated[ float | None, Field( description='Budget allocation for this package in the currency specified by the pricing option', ge=0.0, ), ] = None buyer_ref: Annotated[ str | None, Field(description="Buyer's reference identifier for this package") ] = None creative_assignments: Annotated[ list[creative_assignment.CreativeAssignment] | None, Field(description='Creative assets assigned to this package'), ] = None format_ids_to_provide: Annotated[ list[format_id.FormatId] | None, Field(description='Format IDs that creative assets will be provided for this package'), ] = None impressions: Annotated[ float | None, Field(description='Impression goal for this package', ge=0.0) ] = None pacing: pacing_1.Pacing | None = None package_id: Annotated[str, Field(description="Publisher's unique identifier for the package")] pricing_option_id: Annotated[ str | None, Field( description="ID of the selected pricing option from the product's pricing_options array" ), ] = None product_id: Annotated[ str | None, Field(description='ID of the product this package is based on') ] = None status: package_status.PackageStatus targeting_overlay: targeting.TargetingOverlay | None = NoneBase model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var bid_price : float | Nonevar budget : float | Nonevar buyer_ref : str | Nonevar creative_assignments : list[CreativeAssignment] | Nonevar format_ids_to_provide : list[FormatId] | Nonevar impressions : float | Nonevar model_configvar pacing : Pacing | Nonevar package_id : strvar pricing_option_id : str | Nonevar product_id : str | Nonevar status : PackageStatusvar targeting_overlay : TargetingOverlay | None
class CreatedPackageReference (**data: Any)-
Expand source code
class Package(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) buyer_ref: Annotated[str, Field(description="Buyer's reference identifier for the package")] package_id: Annotated[str, Field(description="Publisher's unique identifier for the package")]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var buyer_ref : strvar model_configvar package_id : str
Inherited members
class PackageRequest (**data: Any)-
Expand source code
class PackageRequest(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) bid_price: Annotated[ float | None, Field( description='Bid price for auction-based CPM pricing (required if using cpm-auction-option)', ge=0.0, ), ] = None budget: Annotated[ float, Field(description="Budget allocation for this package in the media buy's currency", ge=0.0), ] buyer_ref: Annotated[str, Field(description="Buyer's reference identifier for this package")] creative_ids: Annotated[ list[str] | None, Field( description='Creative IDs to assign to this package at creation time (references existing library creatives)' ), ] = None creatives: Annotated[ list[creative_asset.CreativeAsset] | None, Field( description='Full creative objects to upload and assign to this package at creation time (alternative to creative_ids - creatives will be added to library). Supports both static and generative creatives.', max_length=100, ), ] = None format_ids: Annotated[ list[format_id.FormatId] | None, Field( description='Array of format IDs that will be used for this package - must be supported by the product. If omitted, defaults to all formats supported by the product.', min_length=1, ), ] = None pacing: pacing_1.Pacing | None = None pricing_option_id: Annotated[ str, Field( description="ID of the selected pricing option from the product's pricing_options array" ), ] product_id: Annotated[str, Field(description='Product ID for this package')] targeting_overlay: targeting.TargetingOverlay | None = NoneBase model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var bid_price : float | Nonevar budget : floatvar buyer_ref : strvar creative_ids : list[str] | Nonevar creatives : list[CreativeAsset] | Nonevar format_ids : list[FormatId] | Nonevar model_configvar pacing : Pacing | Nonevar pricing_option_id : strvar product_id : strvar targeting_overlay : TargetingOverlay | None
Inherited members
class PackageStatus (*args, **kwds)-
Expand source code
class PackageStatus(Enum): draft = 'draft' active = 'active' paused = 'paused' completed = 'completed'Create a collection of name/value pairs.
Example enumeration:
>>> class Color(Enum): ... RED = 1 ... BLUE = 2 ... GREEN = 3Access them by:
- attribute access::
>>> Color.RED <Color.RED: 1>- value lookup:
>>> Color(1) <Color.RED: 1>- name lookup:
>>> Color['RED'] <Color.RED: 1>Enumerations can be iterated over, and know how many members they have:
>>> len(Color) 3>>> list(Color) [<Color.RED: 1>, <Color.BLUE: 2>, <Color.GREEN: 3>]Methods can be added to enumerations, and members can have their own attributes – see the documentation for details.
Ancestors
- enum.Enum
Class variables
var activevar completedvar draftvar paused
class PreviewCreativeRequest (root: RootModelRootType = PydanticUndefined, **data)-
Expand source code
class PreviewCreativeRequest(RootModel[PreviewCreativeRequest1 | PreviewCreativeRequest2]): root: Annotated[ PreviewCreativeRequest1 | PreviewCreativeRequest2, Field( description='Request to generate previews of one or more creative manifests. Accepts either a single creative request or an array of requests for batch processing.', title='Preview Creative Request', ), ]Usage Documentation
A Pydantic
BaseModelfor the root object of the model.Attributes
root- The root object of the model.
__pydantic_root_model__- Whether the model is a RootModel.
__pydantic_private__- Private fields in the model.
__pydantic_extra__- Extra fields in the model.
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- pydantic.root_model.RootModel[Union[PreviewCreativeRequest1, PreviewCreativeRequest2]]
- pydantic.root_model.RootModel
- pydantic.main.BaseModel
- typing.Generic
Class variables
var model_configvar root : PreviewCreativeRequest1 | PreviewCreativeRequest2
class PreviewCreativeFormatRequest (**data: Any)-
Expand source code
class PreviewCreativeRequest1(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context included in the request payload. Agents must echo this value back unchanged in responses and webhooks. Use for UI/session hints, correlation tokens, or tracking metadata.' ), ] = None creative_manifest: Annotated[ creative_manifest_1.CreativeManifest, Field( description='Complete creative manifest with all required assets (including promoted_offerings if required by the format)' ), ] format_id: Annotated[ format_id_1.FormatId, Field(description='Format identifier for rendering the preview') ] inputs: Annotated[ list[Input] | None, Field( description='Array of input sets for generating multiple preview variants. Each input set defines macros and context values for one preview rendering. If not provided, creative agent will generate default previews.' ), ] = None output_format: Annotated[ OutputFormat | None, Field( description="Output format for previews. 'url' returns preview_url (iframe-embeddable URL), 'html' returns preview_html (raw HTML for direct embedding). Default: 'url' for backward compatibility." ), ] = OutputFormat.url request_type: Annotated[ Literal['single'], Field(description='Discriminator indicating this is a single preview request'), ] template_id: Annotated[ str | None, Field(description='Specific template ID for custom format rendering') ] = NoneBase model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : dict[str, typing.Any] | Nonevar creative_manifest : CreativeManifestvar format_id : FormatIdvar inputs : list[Input] | Nonevar model_configvar output_format : OutputFormat | Nonevar request_type : Literal['single']var template_id : str | None
Inherited members
class PreviewCreativeManifestRequest (**data: Any)-
Expand source code
class PreviewCreativeRequest2(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context included in the request payload. Agents must echo this value back unchanged in responses and webhooks. Use for UI/session hints, correlation tokens, or tracking metadata.' ), ] = None output_format: Annotated[ OutputFormat | None, Field( description="Default output format for all requests in this batch. Individual requests can override this. 'url' returns preview_url (iframe-embeddable URL), 'html' returns preview_html (raw HTML for direct embedding)." ), ] = OutputFormat.url request_type: Annotated[ Literal['batch'], Field(description='Discriminator indicating this is a batch preview request'), ] requests: Annotated[ list[Request], Field( description='Array of preview requests (1-50 items). Each follows the single request structure.', max_length=50, min_length=1, ), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : dict[str, typing.Any] | Nonevar model_configvar output_format : OutputFormat | Nonevar request_type : Literal['batch']var requests : list[Request]
Inherited members
class PreviewCreativeResponse (root: RootModelRootType = PydanticUndefined, **data)-
Expand source code
class PreviewCreativeResponse(RootModel[PreviewCreativeResponse1 | PreviewCreativeResponse2]): root: Annotated[ PreviewCreativeResponse1 | PreviewCreativeResponse2, Field( description='Response containing preview links for one or more creatives. Format matches the request: single preview response for single requests, batch results for batch requests.', title='Preview Creative Response', ), ]Usage Documentation
A Pydantic
BaseModelfor the root object of the model.Attributes
root- The root object of the model.
__pydantic_root_model__- Whether the model is a RootModel.
__pydantic_private__- Private fields in the model.
__pydantic_extra__- Extra fields in the model.
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- pydantic.root_model.RootModel[Union[PreviewCreativeResponse1, PreviewCreativeResponse2]]
- pydantic.root_model.RootModel
- pydantic.main.BaseModel
- typing.Generic
Class variables
var model_configvar root : PreviewCreativeResponse1 | PreviewCreativeResponse2
class PreviewCreativeStaticResponse (**data: Any)-
Expand source code
class PreviewCreativeResponse1(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context echoed inside the preview payload. Opaque metadata such as UI/session hints, correlation tokens, or tracking identifiers.' ), ] = None expires_at: Annotated[ AwareDatetime, Field(description='ISO 8601 timestamp when preview links expire') ] interactive_url: Annotated[ AnyUrl | None, Field( description='Optional URL to an interactive testing page that shows all preview variants with controls to switch between them, modify macro values, and test different scenarios.' ), ] = None previews: Annotated[ list[Preview], Field( description='Array of preview variants. Each preview corresponds to an input set from the request. If no inputs were provided, returns a single default preview.', min_length=1, ), ] response_type: Annotated[ Literal['single'], Field(description='Discriminator indicating this is a single preview response'), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : dict[str, typing.Any] | Nonevar expires_at : pydantic.types.AwareDatetimevar interactive_url : pydantic.networks.AnyUrl | Nonevar model_configvar previews : list[Preview]var response_type : Literal['single']
Inherited members
class PreviewCreativeInteractiveResponse (**data: Any)-
Expand source code
class PreviewCreativeResponse2(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context echoed inside the preview payload. Opaque metadata such as UI/session hints, correlation tokens, or tracking identifiers.' ), ] = None response_type: Annotated[ Literal['batch'], Field(description='Discriminator indicating this is a batch preview response'), ] results: Annotated[ list[Results | Results1], Field( description='Array of preview results corresponding to each request in the same order. results[0] is the result for requests[0], results[1] for requests[1], etc. Order is guaranteed even when some requests fail. Each result contains either a successful preview response or an error.', min_length=1, ), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : dict[str, typing.Any] | Nonevar model_configvar response_type : Literal['batch']var results : list[Results | Results1]
Inherited members
class UrlPreviewRender (**data: Any)-
Expand source code
class PreviewRender1(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) dimensions: Annotated[ Dimensions | None, Field(description='Dimensions for this rendered piece') ] = None embedding: Annotated[ Embedding | None, Field(description='Optional security and embedding metadata for safe iframe integration'), ] = None output_format: Annotated[ Literal['url'], Field(description='Discriminator indicating preview_url is provided') ] preview_url: Annotated[ AnyUrl, Field( description='URL to an HTML page that renders this piece. Can be embedded in an iframe.' ), ] render_id: Annotated[ str, Field(description='Unique identifier for this rendered piece within the variant') ] role: Annotated[ str, Field( description="Semantic role of this rendered piece. Use 'primary' for main content, 'companion' for associated banners, descriptive strings for device variants or custom roles." ), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var dimensions : Dimensions | Nonevar embedding : Embedding | Nonevar model_configvar output_format : Literal['url']var preview_url : pydantic.networks.AnyUrlvar render_id : strvar role : str
Inherited members
class HtmlPreviewRender (**data: Any)-
Expand source code
class PreviewRender2(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) dimensions: Annotated[ Dimensions | None, Field(description='Dimensions for this rendered piece') ] = None embedding: Annotated[ Embedding | None, Field(description='Optional security and embedding metadata') ] = None output_format: Annotated[ Literal['html'], Field(description='Discriminator indicating preview_html is provided') ] preview_html: Annotated[ str, Field( description='Raw HTML for this rendered piece. Can be embedded directly in the page without iframe. Security warning: Only use with trusted creative agents as this bypasses iframe sandboxing.' ), ] render_id: Annotated[ str, Field(description='Unique identifier for this rendered piece within the variant') ] role: Annotated[ str, Field( description="Semantic role of this rendered piece. Use 'primary' for main content, 'companion' for associated banners, descriptive strings for device variants or custom roles." ), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var dimensions : Dimensions | Nonevar embedding : Embedding | Nonevar model_configvar output_format : Literal['html']var preview_html : strvar render_id : strvar role : str
Inherited members
class BothPreviewRender (**data: Any)-
Expand source code
class PreviewRender3(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) dimensions: Annotated[ Dimensions | None, Field(description='Dimensions for this rendered piece') ] = None embedding: Annotated[ Embedding | None, Field(description='Optional security and embedding metadata for safe iframe integration'), ] = None output_format: Annotated[ Literal['both'], Field( description='Discriminator indicating both preview_url and preview_html are provided' ), ] preview_html: Annotated[ str, Field( description='Raw HTML for this rendered piece. Can be embedded directly in the page without iframe. Security warning: Only use with trusted creative agents as this bypasses iframe sandboxing.' ), ] preview_url: Annotated[ AnyUrl, Field( description='URL to an HTML page that renders this piece. Can be embedded in an iframe.' ), ] render_id: Annotated[ str, Field(description='Unique identifier for this rendered piece within the variant') ] role: Annotated[ str, Field( description="Semantic role of this rendered piece. Use 'primary' for main content, 'companion' for associated banners, descriptive strings for device variants or custom roles." ), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var dimensions : Dimensions | Nonevar embedding : Embedding | Nonevar model_configvar output_format : Literal['both']var preview_html : strvar preview_url : pydantic.networks.AnyUrlvar render_id : strvar role : str
Inherited members
class PriceGuidance (**data: Any)-
Expand source code
class PriceGuidance(AdCPBaseModel): floor: Annotated[ float, Field( description='Minimum bid price - publisher will reject bids under this value', ge=0.0 ), ] p25: Annotated[float | None, Field(description='25th percentile winning price', ge=0.0)] = None p50: Annotated[float | None, Field(description='Median winning price', ge=0.0)] = None p75: Annotated[float | None, Field(description='75th percentile winning price', ge=0.0)] = None p90: Annotated[float | None, Field(description='90th percentile winning price', ge=0.0)] = NoneBase model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var floor : floatvar model_configvar p25 : float | Nonevar p50 : float | Nonevar p75 : float | Nonevar p90 : float | None
Inherited members
class PricingModel (*args, **kwds)-
Expand source code
class PricingModel(Enum): cpm = 'cpm' vcpm = 'vcpm' cpc = 'cpc' cpcv = 'cpcv' cpv = 'cpv' cpp = 'cpp' flat_rate = 'flat_rate'Create a collection of name/value pairs.
Example enumeration:
>>> class Color(Enum): ... RED = 1 ... BLUE = 2 ... GREEN = 3Access them by:
- attribute access::
>>> Color.RED <Color.RED: 1>- value lookup:
>>> Color(1) <Color.RED: 1>- name lookup:
>>> Color['RED'] <Color.RED: 1>Enumerations can be iterated over, and know how many members they have:
>>> len(Color) 3>>> list(Color) [<Color.RED: 1>, <Color.BLUE: 2>, <Color.GREEN: 3>]Methods can be added to enumerations, and members can have their own attributes – see the documentation for details.
Ancestors
- enum.Enum
Class variables
var cpcvar cpcvvar cpmvar cppvar cpvvar flat_ratevar vcpm
class Product (**data: Any)-
Expand source code
class Product(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) brief_relevance: Annotated[ str | None, Field( description='Explanation of why this product matches the brief (only included when brief is provided)' ), ] = None creative_policy: creative_policy_1.CreativePolicy | None = None delivery_measurement: Annotated[ DeliveryMeasurement, Field( description='Measurement provider and methodology for delivery metrics. The buyer accepts the declared provider as the source of truth for the buy. REQUIRED for all products.' ), ] delivery_type: delivery_type_1.DeliveryType description: Annotated[ str, Field(description='Detailed description of the product and its inventory') ] estimated_exposures: Annotated[ int | None, Field(description='Estimated exposures/impressions for guaranteed products', ge=0), ] = None expires_at: Annotated[ AwareDatetime | None, Field(description='Expiration timestamp for custom products') ] = None format_ids: Annotated[ list[format_id_1.FormatId], Field( description='Array of supported creative format IDs - structured format_id objects with agent_url and id' ), ] is_custom: Annotated[bool | None, Field(description='Whether this is a custom product')] = None measurement: measurement_1.Measurement | None = None name: Annotated[str, Field(description='Human-readable product name')] placements: Annotated[ list[placement.Placement] | None, Field( description='Optional array of specific placements within this product. When provided, buyers can target specific placements when assigning creatives.', min_length=1, ), ] = None pricing_options: Annotated[ list[ cpm_fixed_option.CpmFixedRatePricingOption | cpm_auction_option.CpmAuctionPricingOption | vcpm_fixed_option.VcpmFixedRatePricingOption | vcpm_auction_option.VcpmAuctionPricingOption | cpc_option.CpcPricingOption | cpcv_option.CpcvPricingOption | cpv_option.CpvPricingOption | cpp_option.CppPricingOption | flat_rate_option.FlatRatePricingOption ], Field(description='Available pricing models for this product', min_length=1), ] product_card: Annotated[ ProductCard | None, Field( description='Optional standard visual card (300x400px) for displaying this product in user interfaces. Can be rendered via preview_creative or pre-generated.' ), ] = None product_card_detailed: Annotated[ ProductCardDetailed | None, Field( description='Optional detailed card with carousel and full specifications. Provides rich product presentation similar to media kit pages.' ), ] = None product_id: Annotated[str, Field(description='Unique identifier for the product')] publisher_properties: Annotated[ list[ publisher_property_selector.PublisherPropertySelector1 | publisher_property_selector.PublisherPropertySelector2 | publisher_property_selector.PublisherPropertySelector3 ], Field( description="Publisher properties covered by this product. Buyers fetch actual property definitions from each publisher's adagents.json and validate agent authorization. Selection patterns mirror the authorization patterns in adagents.json for consistency.", min_length=1, ), ] reporting_capabilities: reporting_capabilities_1.ReportingCapabilities | None = NoneBase model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var brief_relevance : str | Nonevar creative_policy : CreativePolicy | Nonevar delivery_measurement : DeliveryMeasurementvar delivery_type : DeliveryTypevar description : strvar estimated_exposures : int | Nonevar expires_at : pydantic.types.AwareDatetime | Nonevar format_ids : list[FormatId]var is_custom : bool | Nonevar measurement : Measurement | Nonevar model_configvar name : strvar placements : list[Placement] | Nonevar pricing_options : list[CpmFixedRatePricingOption | CpmAuctionPricingOption | VcpmFixedRatePricingOption | VcpmAuctionPricingOption | CpcPricingOption | CpcvPricingOption | CpvPricingOption | CppPricingOption | FlatRatePricingOption]var product_card : ProductCard | Nonevar product_card_detailed : ProductCardDetailed | Nonevar product_id : strvar publisher_properties : list[PublisherPropertySelector1 | PublisherPropertySelector2 | PublisherPropertySelector3]var reporting_capabilities : ReportingCapabilities | None
Inherited members
class Property (**data: Any)-
Expand source code
class Property(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) identifiers: Annotated[ list[Identifier], Field(description='Array of identifiers for this property', min_length=1) ] name: Annotated[str, Field(description='Human-readable property name')] property_id: Annotated[ str | None, Field( description="Unique identifier for this property (optional). Enables referencing properties by ID instead of repeating full objects. Recommended format: lowercase with underscores (e.g., 'cnn_ctv_app', 'instagram_mobile')", pattern='^[a-z0-9_]+$', ), ] = None property_type: Annotated[PropertyType, Field(description='Type of advertising property')] publisher_domain: Annotated[ str | None, Field( description='Domain where adagents.json should be checked for authorization validation. Required for list_authorized_properties response. Optional in adagents.json (file location implies domain).' ), ] = None tags: Annotated[ list[Tag] | None, Field( description='Tags for categorization and grouping (e.g., network membership, content categories)' ), ] = NoneBase model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var identifiers : list[Identifier]var model_configvar name : strvar property_id : str | Nonevar property_type : PropertyTypevar publisher_domain : str | None
Inherited members
class PropertyId (root: RootModelRootType = PydanticUndefined, **data)-
Expand source code
class PropertyId(RootModel[str]): root: Annotated[str, Field(pattern='^[a-z0-9_]+$')]Usage Documentation
A Pydantic
BaseModelfor the root object of the model.Attributes
root- The root object of the model.
__pydantic_root_model__- Whether the model is a RootModel.
__pydantic_private__- Private fields in the model.
__pydantic_extra__- Extra fields in the model.
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- pydantic.root_model.RootModel[str]
- pydantic.root_model.RootModel
- pydantic.main.BaseModel
- typing.Generic
Subclasses
Class variables
var model_configvar root : str
class PropertyTag (root: RootModelRootType = PydanticUndefined, **data)-
Expand source code
class PropertyTag(PropertyId): passUsage Documentation
A Pydantic
BaseModelfor the root object of the model.Attributes
root- The root object of the model.
__pydantic_root_model__- Whether the model is a RootModel.
__pydantic_private__- Private fields in the model.
__pydantic_extra__- Extra fields in the model.
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- PropertyId
- pydantic.root_model.RootModel[str]
- pydantic.root_model.RootModel
- pydantic.main.BaseModel
- typing.Generic
Class variables
var model_config
class Protocol (*args, **kwds)-
Expand source code
class Protocol(str, Enum): """Supported protocols.""" A2A = "a2a" MCP = "mcp"Supported protocols.
Ancestors
- builtins.str
- enum.Enum
Class variables
var A2Avar MCP
class ProvidePerformanceFeedbackRequest (**data: Any)-
Expand source code
class ProvidePerformanceFeedbackRequest(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context included in the request payload. Agentsmust echo this value back unchanged in responses and webhooks. Use for UI/session hints, correlation tokens, or tracking metadata.' ), ] = None creative_id: Annotated[ str | None, Field( description='Specific creative asset (if feedback is creative-specific)', min_length=1 ), ] = None feedback_source: Annotated[ FeedbackSource | None, Field(description='Source of the performance data') ] = FeedbackSource.buyer_attribution measurement_period: Annotated[ MeasurementPeriod, Field(description='Time period for performance measurement') ] media_buy_id: Annotated[ str, Field(description="Publisher's media buy identifier", min_length=1) ] metric_type: Annotated[ MetricType | None, Field(description='The business metric being measured') ] = MetricType.overall_performance package_id: Annotated[ str | None, Field( description='Specific package within the media buy (if feedback is package-specific)', min_length=1, ), ] = None performance_index: Annotated[ float, Field( description='Normalized performance score (0.0 = no value, 1.0 = expected, >1.0 = above expected)', ge=0.0, ), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : dict[str, typing.Any] | Nonevar creative_id : str | Nonevar feedback_source : FeedbackSource | Nonevar measurement_period : MeasurementPeriodvar media_buy_id : strvar metric_type : MetricType | Nonevar model_configvar package_id : str | Nonevar performance_index : float
Inherited members
class ProvidePerformanceFeedbackResponse (root: RootModelRootType = PydanticUndefined, **data)-
Expand source code
class ProvidePerformanceFeedbackResponse( RootModel[ProvidePerformanceFeedbackResponse1 | ProvidePerformanceFeedbackResponse2] ): root: Annotated[ ProvidePerformanceFeedbackResponse1 | ProvidePerformanceFeedbackResponse2, Field( description='Response payload for provide_performance_feedback task. Returns either success confirmation OR error information, never both.', title='Provide Performance Feedback Response', ), ]Usage Documentation
A Pydantic
BaseModelfor the root object of the model.Attributes
root- The root object of the model.
__pydantic_root_model__- Whether the model is a RootModel.
__pydantic_private__- Private fields in the model.
__pydantic_extra__- Extra fields in the model.
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- pydantic.root_model.RootModel[Union[ProvidePerformanceFeedbackResponse1, ProvidePerformanceFeedbackResponse2]]
- pydantic.root_model.RootModel
- pydantic.main.BaseModel
- typing.Generic
Class variables
var model_configvar root : ProvidePerformanceFeedbackResponse1 | ProvidePerformanceFeedbackResponse2
class ProvidePerformanceFeedbackSuccessResponse (**data: Any)-
Expand source code
class ProvidePerformanceFeedbackResponse1(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context echoed inside the task payload. Opaque metadata such as UI/session hints, correlation tokens, or tracking identifiers.' ), ] = None success: Annotated[ Literal[True], Field(description='Whether the performance feedback was successfully received'), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : dict[str, typing.Any] | Nonevar model_configvar success : Literal[True]
Inherited members
class ProvidePerformanceFeedbackErrorResponse (**data: Any)-
Expand source code
class ProvidePerformanceFeedbackResponse2(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context echoed inside the task payload. Opaque metadata such as UI/session hints, correlation tokens, or tracking identifiers.' ), ] = None errors: Annotated[ list[error.Error], Field( description='Array of errors explaining why feedback was rejected (e.g., invalid measurement period, missing campaign data)', min_length=1, ), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : dict[str, typing.Any] | Nonevar errors : list[Error]var model_config
Inherited members
class PublisherPropertiesAll (**data: Any)-
Expand source code
class PublisherPropertySelector1(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) publisher_domain: Annotated[ str, Field( description="Domain where publisher's adagents.json is hosted (e.g., 'cnn.com')", pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$', ), ] selection_type: Annotated[ Literal['all'], Field( description='Discriminator indicating all properties from this publisher are included' ), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var model_configvar publisher_domain : strvar selection_type : Literal['all']
Inherited members
class PublisherPropertiesById (**data: Any)-
Expand source code
class PublisherPropertySelector2(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) property_ids: Annotated[ list[PropertyId], Field(description="Specific property IDs from the publisher's adagents.json", min_length=1), ] publisher_domain: Annotated[ str, Field( description="Domain where publisher's adagents.json is hosted (e.g., 'cnn.com')", pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$', ), ] selection_type: Annotated[ Literal['by_id'], Field(description='Discriminator indicating selection by specific property IDs'), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var model_configvar property_ids : list[PropertyId]var publisher_domain : strvar selection_type : Literal['by_id']
Inherited members
class PublisherPropertiesByTag (**data: Any)-
Expand source code
class PublisherPropertySelector3(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) property_tags: Annotated[ list[PropertyTag], Field( description="Property tags from the publisher's adagents.json. Selector covers all properties with these tags", min_length=1, ), ] publisher_domain: Annotated[ str, Field( description="Domain where publisher's adagents.json is hosted (e.g., 'cnn.com')", pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$', ), ] selection_type: Annotated[ Literal['by_tag'], Field(description='Discriminator indicating selection by property tags') ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var model_configvar publisher_domain : strvar selection_type : Literal['by_tag']
Inherited members
class PushNotificationConfig (**data: Any)-
Expand source code
class PushNotificationConfig(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) authentication: Annotated[ Authentication, Field(description='Authentication configuration for webhook delivery (A2A-compatible)'), ] token: Annotated[ str | None, Field( description='Optional client-provided token for webhook validation. Echoed back in webhook payload to validate request authenticity.', min_length=16, ), ] = None url: Annotated[AnyUrl, Field(description='Webhook endpoint URL for task status notifications')]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Subclasses
Class variables
var authentication : Authenticationvar model_configvar token : str | Nonevar url : pydantic.networks.AnyUrl
Inherited members
class MediaSubAsset (**data: Any)-
Expand source code
class SubAsset1(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) asset_id: Annotated[ str, Field(description='Unique identifier for the asset within the creative') ] asset_kind: Annotated[ Literal['media'], Field(description='Discriminator indicating this is a media asset with content_uri'), ] asset_type: Annotated[ str, Field( description='Type of asset. Common types: thumbnail_image, product_image, featured_image, logo' ), ] content_uri: Annotated[AnyUrl, Field(description='URL for media assets (images, videos, etc.)')]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var asset_id : strvar asset_kind : Literal['media']var asset_type : strvar content_uri : pydantic.networks.AnyUrlvar model_config
Inherited members
class TextSubAsset (**data: Any)-
Expand source code
class SubAsset2(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) asset_id: Annotated[ str, Field(description='Unique identifier for the asset within the creative') ] asset_kind: Annotated[ Literal['text'], Field(description='Discriminator indicating this is a text asset with content'), ] asset_type: Annotated[ str, Field( description='Type of asset. Common types: headline, body_text, cta_text, price_text, sponsor_name, author_name, click_url' ), ] content: Annotated[ str | list[str], Field( description='Text content for text-based assets like headlines, body text, CTA text, etc.' ), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var asset_id : strvar asset_kind : Literal['text']var asset_type : strvar content : str | list[str]var model_config
Inherited members
class SyncCreativesRequest (**data: Any)-
Expand source code
class SyncCreativesRequest(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) assignments: Annotated[ dict[str, list[str]] | None, Field(description='Optional bulk assignment of creatives to packages'), ] = None context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context included in the request payload. Agents must echo this value back unchanged in responses and webhooks. Use for UI/session hints, correlation tokens, or tracking metadata.' ), ] = None creatives: Annotated[ list[creative_asset.CreativeAsset], Field(description='Array of creative assets to sync (create or update)', max_length=100), ] delete_missing: Annotated[ bool | None, Field( description='When true, creatives not included in this sync will be archived. Use with caution for full library replacement.' ), ] = False dry_run: Annotated[ bool | None, Field( description='When true, preview changes without applying them. Returns what would be created/updated/deleted.' ), ] = False patch: Annotated[ bool | None, Field( description='When true, only provided fields are updated (partial update). When false, entire creative is replaced (full upsert).' ), ] = False push_notification_config: Annotated[ push_notification_config_1.PushNotificationConfig | None, Field( description='Optional webhook configuration for async sync notifications. Publisher will send webhook when sync completes if operation takes longer than immediate response time (typically for large bulk operations or manual approval/HITL).' ), ] = None validation_mode: Annotated[ ValidationMode | None, Field( description="Validation strictness. 'strict' fails entire sync on any validation error. 'lenient' processes valid creatives and reports errors." ), ] = ValidationMode.strictBase model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var assignments : dict[str, list[str]] | Nonevar context : dict[str, typing.Any] | Nonevar creatives : list[CreativeAsset]var delete_missing : bool | Nonevar dry_run : bool | Nonevar model_configvar patch : bool | Nonevar push_notification_config : PushNotificationConfig | Nonevar validation_mode : ValidationMode | None
Inherited members
class SyncCreativesResponse (root: RootModelRootType = PydanticUndefined, **data)-
Expand source code
class SyncCreativesResponse(RootModel[SyncCreativesResponse1 | SyncCreativesResponse2]): root: Annotated[ SyncCreativesResponse1 | SyncCreativesResponse2, Field( description='Response from creative sync operation. Returns either per-creative results (best-effort processing) OR operation-level errors (complete failure). This enforces atomic semantics at the operation level while allowing per-item failures within successful operations.', title='Sync Creatives Response', ), ]Usage Documentation
A Pydantic
BaseModelfor the root object of the model.Attributes
root- The root object of the model.
__pydantic_root_model__- Whether the model is a RootModel.
__pydantic_private__- Private fields in the model.
__pydantic_extra__- Extra fields in the model.
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- pydantic.root_model.RootModel[Union[SyncCreativesResponse1, SyncCreativesResponse2]]
- pydantic.root_model.RootModel
- pydantic.main.BaseModel
- typing.Generic
Class variables
var model_configvar root : SyncCreativesResponse1 | SyncCreativesResponse2
class SyncCreativesSuccessResponse (**data: Any)-
Expand source code
class SyncCreativesResponse1(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context echoed inside the task payload. Opaque metadata such as UI/session hints, correlation tokens, or tracking identifiers.' ), ] = None creatives: Annotated[ list[Creative], Field( description="Results for each creative processed. Items with action='failed' indicate per-item validation/processing failures, not operation-level failures." ), ] dry_run: Annotated[ bool | None, Field(description='Whether this was a dry run (no actual changes made)') ] = NoneBase model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : dict[str, typing.Any] | Nonevar creatives : list[Creative]var dry_run : bool | Nonevar model_config
Inherited members
class SyncCreativesErrorResponse (**data: Any)-
Expand source code
class SyncCreativesResponse2(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context echoed inside the task payload. Opaque metadata such as UI/session hints, correlation tokens, or tracking identifiers.' ), ] = None errors: Annotated[ list[error.Error], Field( description='Operation-level errors that prevented processing any creatives (e.g., authentication failure, service unavailable, invalid request format)', min_length=1, ), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : dict[str, typing.Any] | Nonevar errors : list[Error]var model_config
Inherited members
class TaskResult (**data: Any)-
Expand source code
class TaskResult(BaseModel, Generic[T]): """Result from task execution.""" model_config = ConfigDict(arbitrary_types_allowed=True) status: TaskStatus data: T | None = None message: str | None = None # Human-readable message from agent (e.g., MCP content text) submitted: SubmittedInfo | None = None needs_input: NeedsInputInfo | None = None error: str | None = None success: bool = Field(default=True) metadata: dict[str, Any] | None = None debug_info: DebugInfo | None = NoneResult from task execution.
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- pydantic.main.BaseModel
- typing.Generic
Subclasses
- adcp.types.core.TaskResult[ActivateSignalResponse]
- adcp.types.core.TaskResult[Any]
- adcp.types.core.TaskResult[GetMediaBuyDeliveryResponse]
- adcp.types.core.TaskResult[GetProductsResponse]
- adcp.types.core.TaskResult[GetSignalsResponse]
- adcp.types.core.TaskResult[ListAuthorizedPropertiesResponse]
- adcp.types.core.TaskResult[ListCreativeFormatsResponse]
- adcp.types.core.TaskResult[ListCreativesResponse]
- adcp.types.core.TaskResult[PreviewCreativeResponse]
- adcp.types.core.TaskResult[ProvidePerformanceFeedbackResponse]
- adcp.types.core.TaskResult[SyncCreativesResponse]
Class variables
var data : ~T | Nonevar debug_info : DebugInfo | Nonevar error : str | Nonevar message : str | Nonevar metadata : dict[str, typing.Any] | Nonevar model_configvar needs_input : NeedsInputInfo | Nonevar status : TaskStatusvar submitted : SubmittedInfo | Nonevar success : bool
class TaskStatus (*args, **kwds)-
Expand source code
class TaskStatus(str, Enum): """Task execution status.""" COMPLETED = "completed" SUBMITTED = "submitted" NEEDS_INPUT = "needs_input" FAILED = "failed" WORKING = "working"Task execution status.
Ancestors
- builtins.str
- enum.Enum
Class variables
var COMPLETEDvar FAILEDvar NEEDS_INPUTvar SUBMITTEDvar WORKING
class GeneratedTaskStatus (*args, **kwds)-
Expand source code
class TaskStatus(Enum): submitted = 'submitted' working = 'working' input_required = 'input-required' completed = 'completed' canceled = 'canceled' failed = 'failed' rejected = 'rejected' auth_required = 'auth-required' unknown = 'unknown'Create a collection of name/value pairs.
Example enumeration:
>>> class Color(Enum): ... RED = 1 ... BLUE = 2 ... GREEN = 3Access them by:
- attribute access::
>>> Color.RED <Color.RED: 1>- value lookup:
>>> Color(1) <Color.RED: 1>- name lookup:
>>> Color['RED'] <Color.RED: 1>Enumerations can be iterated over, and know how many members they have:
>>> len(Color) 3>>> list(Color) [<Color.RED: 1>, <Color.BLUE: 2>, <Color.GREEN: 3>]Methods can be added to enumerations, and members can have their own attributes – see the documentation for details.
Ancestors
- enum.Enum
Class variables
var auth_requiredvar canceledvar completedvar failedvar input_requiredvar rejectedvar submittedvar unknownvar working
class UpdateMediaBuyRequest (root: RootModelRootType = PydanticUndefined, **data)-
Expand source code
class UpdateMediaBuyRequest(RootModel[UpdateMediaBuyRequest1 | UpdateMediaBuyRequest2]): root: Annotated[ UpdateMediaBuyRequest1 | UpdateMediaBuyRequest2, Field( description='Request parameters for updating campaign and package settings', title='Update Media Buy Request', ), ]Usage Documentation
A Pydantic
BaseModelfor the root object of the model.Attributes
root- The root object of the model.
__pydantic_root_model__- Whether the model is a RootModel.
__pydantic_private__- Private fields in the model.
__pydantic_extra__- Extra fields in the model.
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- pydantic.root_model.RootModel[Union[UpdateMediaBuyRequest1, UpdateMediaBuyRequest2]]
- pydantic.root_model.RootModel
- pydantic.main.BaseModel
- typing.Generic
Class variables
var model_configvar root : UpdateMediaBuyRequest1 | UpdateMediaBuyRequest2
class UpdateMediaBuyPackagesRequest (**data: Any)-
Expand source code
class UpdateMediaBuyRequest1(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) active: Annotated[bool | None, Field(description='Pause/resume the entire media buy')] = None buyer_ref: Annotated[ str | None, Field(description="Buyer's reference for the media buy to update") ] = None context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context included in the request payload. Agents must echo this value back unchanged in responses and webhooks. Use for UI/session hints, correlation tokens, or tracking metadata.' ), ] = None end_time: Annotated[ AwareDatetime | None, Field(description='New end date/time in ISO 8601 format') ] = None media_buy_id: Annotated[str, Field(description="Publisher's ID of the media buy to update")] packages: Annotated[ list[Packages | Packages1] | None, Field(description='Package-specific updates') ] = None push_notification_config: Annotated[ push_notification_config_1.PushNotificationConfig | None, Field( description='Optional webhook configuration for async update notifications. Publisher will send webhook when update completes if operation takes longer than immediate response time.' ), ] = None start_time: Annotated[ str | AwareDatetime | None, Field( description="Campaign start timing: 'asap' or ISO 8601 date-time", title='Start Timing' ), ] = NoneBase model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var active : bool | Nonevar buyer_ref : str | Nonevar context : dict[str, typing.Any] | Nonevar end_time : pydantic.types.AwareDatetime | Nonevar media_buy_id : strvar model_configvar packages : list[Packages | Packages1] | Nonevar push_notification_config : PushNotificationConfig | Nonevar start_time : str | pydantic.types.AwareDatetime | None
Inherited members
class UpdateMediaBuyPropertiesRequest (**data: Any)-
Expand source code
class UpdateMediaBuyRequest2(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) active: Annotated[bool | None, Field(description='Pause/resume the entire media buy')] = None buyer_ref: Annotated[str, Field(description="Buyer's reference for the media buy to update")] context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context included in the request payload. Agents must echo this value back unchanged in responses and webhooks. Use for UI/session hints, correlation tokens, or tracking metadata.' ), ] = None end_time: Annotated[ AwareDatetime | None, Field(description='New end date/time in ISO 8601 format') ] = None media_buy_id: Annotated[ str | None, Field(description="Publisher's ID of the media buy to update") ] = None packages: Annotated[ list[Packages2 | Packages3] | None, Field(description='Package-specific updates') ] = None push_notification_config: Annotated[ push_notification_config_1.PushNotificationConfig | None, Field( description='Optional webhook configuration for async update notifications. Publisher will send webhook when update completes if operation takes longer than immediate response time.' ), ] = None start_time: Annotated[ str | AwareDatetime | None, Field( description="Campaign start timing: 'asap' or ISO 8601 date-time", title='Start Timing' ), ] = NoneBase model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var active : bool | Nonevar buyer_ref : strvar context : dict[str, typing.Any] | Nonevar end_time : pydantic.types.AwareDatetime | Nonevar media_buy_id : str | Nonevar model_configvar packages : list[Packages | Packages1] | Nonevar push_notification_config : PushNotificationConfig | Nonevar start_time : str | pydantic.types.AwareDatetime | None
Inherited members
class UpdateMediaBuyResponse (root: RootModelRootType = PydanticUndefined, **data)-
Expand source code
class UpdateMediaBuyResponse(RootModel[UpdateMediaBuyResponse1 | UpdateMediaBuyResponse2]): root: Annotated[ UpdateMediaBuyResponse1 | UpdateMediaBuyResponse2, Field( description='Response payload for update_media_buy task. Returns either complete success data OR error information, never both. This enforces atomic operation semantics - updates are either fully applied or not applied at all.', title='Update Media Buy Response', ), ]Usage Documentation
A Pydantic
BaseModelfor the root object of the model.Attributes
root- The root object of the model.
__pydantic_root_model__- Whether the model is a RootModel.
__pydantic_private__- Private fields in the model.
__pydantic_extra__- Extra fields in the model.
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- pydantic.root_model.RootModel[Union[UpdateMediaBuyResponse1, UpdateMediaBuyResponse2]]
- pydantic.root_model.RootModel
- pydantic.main.BaseModel
- typing.Generic
Class variables
var model_configvar root : UpdateMediaBuyResponse1 | UpdateMediaBuyResponse2
class UpdateMediaBuySuccessResponse (**data: Any)-
Expand source code
class UpdateMediaBuyResponse1(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) affected_packages: Annotated[ list[AffectedPackage] | None, Field(description='Array of packages that were modified') ] = None buyer_ref: Annotated[str, Field(description="Buyer's reference identifier for the media buy")] context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context echoed inside the task payload. Opaque metadata such as UI/session hints, correlation tokens, or tracking identifiers.' ), ] = None implementation_date: Annotated[ AwareDatetime | None, Field(description='ISO 8601 timestamp when changes take effect (null if pending approval)'), ] = None media_buy_id: Annotated[str, Field(description="Publisher's identifier for the media buy")]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var affected_packages : list[AffectedPackage] | Nonevar buyer_ref : strvar context : dict[str, typing.Any] | Nonevar implementation_date : pydantic.types.AwareDatetime | Nonevar media_buy_id : strvar model_config
Inherited members
class UpdateMediaBuyErrorResponse (**data: Any)-
Expand source code
class UpdateMediaBuyResponse2(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) context: Annotated[ dict[str, Any] | None, Field( description='Initiator-provided context echoed inside the task payload. Opaque metadata such as UI/session hints, correlation tokens, or tracking identifiers.' ), ] = None errors: Annotated[ list[error.Error], Field(description='Array of errors explaining why the operation failed', min_length=1), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : dict[str, typing.Any] | Nonevar errors : list[Error]var model_config
Inherited members
class ValidationError (*args, **kwargs)-
Expand source code
class ValidationError(ValueError): """Raised when runtime validation fails.""" passRaised when runtime validation fails.
Ancestors
- builtins.ValueError
- builtins.Exception
- builtins.BaseException
class UrlVastAsset (**data: Any)-
Expand source code
class VastAsset1(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) delivery_type: Annotated[ Literal['url'], Field(description='Discriminator indicating VAST is delivered via URL endpoint'), ] duration_ms: Annotated[ int | None, Field(description='Expected video duration in milliseconds (if known)', ge=0) ] = None tracking_events: Annotated[ list[TrackingEvent] | None, Field(description='Tracking events supported by this VAST tag') ] = None url: Annotated[AnyUrl, Field(description='URL endpoint that returns VAST XML')] vast_version: Annotated[VastVersion | None, Field(description='VAST specification version')] = ( None ) vpaid_enabled: Annotated[ bool | None, Field(description='Whether VPAID (Video Player-Ad Interface Definition) is supported'), ] = NoneBase model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var delivery_type : Literal['url']var duration_ms : int | Nonevar model_configvar tracking_events : list[TrackingEvent] | Nonevar url : pydantic.networks.AnyUrlvar vast_version : VastVersion | Nonevar vpaid_enabled : bool | None
Inherited members
class InlineVastAsset (**data: Any)-
Expand source code
class VastAsset2(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) content: Annotated[str, Field(description='Inline VAST XML content')] delivery_type: Annotated[ Literal['inline'], Field(description='Discriminator indicating VAST is delivered as inline XML content'), ] duration_ms: Annotated[ int | None, Field(description='Expected video duration in milliseconds (if known)', ge=0) ] = None tracking_events: Annotated[ list[TrackingEvent] | None, Field(description='Tracking events supported by this VAST tag') ] = None vast_version: Annotated[VastVersion | None, Field(description='VAST specification version')] = ( None ) vpaid_enabled: Annotated[ bool | None, Field(description='Whether VPAID (Video Player-Ad Interface Definition) is supported'), ] = NoneBase model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var content : strvar delivery_type : Literal['inline']var duration_ms : int | Nonevar model_configvar tracking_events : list[TrackingEvent] | Nonevar vast_version : VastVersion | Nonevar vpaid_enabled : bool | None
Inherited members
class VcpmAuctionPricingOption (**data: Any)-
Expand source code
class VcpmAuctionPricingOption(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) currency: Annotated[ str, Field( description='ISO 4217 currency code', examples=['USD', 'EUR', 'GBP', 'JPY'], pattern='^[A-Z]{3}$', ), ] is_fixed: Annotated[ Literal[False], Field(description='Whether this is a fixed rate (true) or auction-based (false)'), ] min_spend_per_package: Annotated[ float | None, Field( description='Minimum spend requirement per package using this pricing option, in the specified currency', ge=0.0, ), ] = None price_guidance: Annotated[ PriceGuidance, Field(description='Statistical guidance for auction pricing') ] pricing_model: Annotated[ Literal['vcpm'], Field(description='Cost per 1,000 viewable impressions (MRC standard)') ] pricing_option_id: Annotated[ str, Field( description="Unique identifier for this pricing option within the product (e.g., 'vcpm_usd_auction')" ), ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var currency : strvar is_fixed : Literal[False]var min_spend_per_package : float | Nonevar model_configvar price_guidance : PriceGuidancevar pricing_model : Literal['vcpm']var pricing_option_id : str
Inherited members
class VcpmFixedRatePricingOption (**data: Any)-
Expand source code
class VcpmFixedRatePricingOption(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) currency: Annotated[ str, Field( description='ISO 4217 currency code', examples=['USD', 'EUR', 'GBP', 'JPY'], pattern='^[A-Z]{3}$', ), ] is_fixed: Annotated[ Literal[True], Field(description='Whether this is a fixed rate (true) or auction-based (false)'), ] min_spend_per_package: Annotated[ float | None, Field( description='Minimum spend requirement per package using this pricing option, in the specified currency', ge=0.0, ), ] = None pricing_model: Annotated[ Literal['vcpm'], Field(description='Cost per 1,000 viewable impressions (MRC standard)') ] pricing_option_id: Annotated[ str, Field( description="Unique identifier for this pricing option within the product (e.g., 'vcpm_usd_guaranteed')" ), ] rate: Annotated[ float, Field(description='Fixed vCPM rate (cost per 1,000 viewable impressions)', ge=0.0) ]Base model for AdCP types with spec-compliant serialization.
AdCP JSON schemas use additionalProperties: false and do not allow null for optional fields. Therefore, optional fields must be omitted entirely when not present (not sent as null).
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var currency : strvar is_fixed : Literal[True]var min_spend_per_package : float | Nonevar model_configvar pricing_model : Literal['vcpm']var pricing_option_id : strvar rate : float
Inherited members
class WebhookMetadata (**data: Any)-
Expand source code
class WebhookMetadata(BaseModel): """Metadata passed to webhook handlers.""" operation_id: str agent_id: str task_type: str status: TaskStatus sequence_number: int | None = None notification_type: Literal["scheduled", "final", "delayed"] | None = None timestamp: strMetadata passed to webhook handlers.
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- pydantic.main.BaseModel
Class variables
var agent_id : strvar model_configvar notification_type : Literal['scheduled', 'final', 'delayed'] | Nonevar operation_id : strvar sequence_number : int | Nonevar status : TaskStatusvar task_type : strvar timestamp : str