Handle webhook from agent (async task status updates and completions)
Accepts webhook payloads from both MCP and A2A protocols:
The method normalizes both formats so handlers receive the unwrapped AdCP response data (AdCPAsyncResponseData), not the raw protocol structure.
Protocol-specific webhook payload (MCPWebhookPayload | Task | TaskStatusUpdateEvent)
Task type (e.g create_media_buy) from url param or url part of the webhook delivery
Operation id (e.g used for client app to track the operation) from the param or url part of the webhook delivery
Optionalsignature: stringX-ADCP-Signature header (format: "sha256=...")
Optionaltimestamp: string | numberX-ADCP-Timestamp header (Unix timestamp)
OptionalrawBody: stringWhether webhook was handled successfully
app.post('/webhook/:taskType', async (req, res) => {
const signature = req.headers['x-adcp-signature'];
const timestamp = req.headers['x-adcp-timestamp'];
try {
const handled = await client.handleWebhook(req.body, signature, timestamp, req.params.taskType);
res.status(200).json({ received: handled });
} catch (error) {
res.status(401).json({ error: error.message });
}
});
Generate webhook URL using macro substitution
Type of task (e.g., 'get_products', 'media_buy_delivery')
Operation ID for this request
Full webhook URL with macros replaced
// With template: "https://myapp.com/webhook/{task_type}/{agent_id}/{operation_id}"
const webhookUrl = client.getWebhookUrl('sync_creatives', 'op_123');
// Returns: https://myapp.com/webhook/sync_creatives/agent_x/op_123
// With template: "https://myapp.com/webhook?agent={agent_id}&op={operation_id}"
const webhookUrl = client.getWebhookUrl('sync_creatives', 'op_123');
// Returns: https://myapp.com/webhook?agent=agent_x&op=op_123
Create an HTTP webhook handler that automatically verifies signatures
This helper creates a standard HTTP handler (Express/Next.js/etc.) that:
HTTP handler function compatible with Express, Next.js, etc.
Verify webhook signature using HMAC-SHA256 per AdCP spec.
HMAC is computed over the raw HTTP body bytes — the exact bytes received on the wire, before JSON parsing. This ensures cross-language interop since different JSON serializers may produce different byte representations of the same logical payload.
For backward compatibility, a parsed object is still accepted but will be re-serialized with JSON.stringify, which may not match the sender's bytes. Always prefer passing the raw body string.
Signature format: sha256={hex_signature} Message format: {timestamp}.{raw_body}
Raw HTTP body string (preferred) or parsed payload object (deprecated)
X-ADCP-Signature header value (format: "sha256=...")
X-ADCP-Timestamp header value (Unix timestamp)
true if signature is valid
Discover available advertising products
Product discovery parameters
OptionalinputHandler: InputHandlerHandler for clarification requests
Optionaloptions: TaskOptionsTask execution options
List available creative formats
Format listing parameters
OptionalinputHandler: InputHandlerHandler for clarification requests
Optionaloptions: TaskOptionsTask execution options
Create a new media buy
Media buy creation parameters
OptionalinputHandler: InputHandlerHandler for clarification requests
Optionaloptions: TaskOptionsTask execution options
Update an existing media buy
Media buy update parameters
OptionalinputHandler: InputHandlerHandler for clarification requests
Optionaloptions: TaskOptionsTask execution options
Sync creative assets
Creative sync parameters
OptionalinputHandler: InputHandlerHandler for clarification requests
Optionaloptions: TaskOptionsTask execution options
List creative assets
Creative listing parameters
OptionalinputHandler: InputHandlerHandler for clarification requests
Optionaloptions: TaskOptionsTask execution options
Preview a creative
Preview creative parameters
OptionalinputHandler: InputHandlerHandler for clarification requests
Optionaloptions: TaskOptionsTask execution options
Get media buy status, creative approvals, and optional delivery snapshots
Request parameters
OptionalinputHandler: InputHandlerHandler for clarification requests
Optionaloptions: TaskOptionsTask execution options
Get media buy delivery information
Delivery information parameters
OptionalinputHandler: InputHandlerHandler for clarification requests
Optionaloptions: TaskOptionsTask execution options
Provide performance feedback
Performance feedback parameters
OptionalinputHandler: InputHandlerHandler for clarification requests
Optionaloptions: TaskOptionsTask execution options
Get audience signals
Signals request parameters
OptionalinputHandler: InputHandlerHandler for clarification requests
Optionaloptions: TaskOptionsTask execution options
Activate audience signals
Signal activation parameters
OptionalinputHandler: InputHandlerHandler for clarification requests
Optionaloptions: TaskOptionsTask execution options
Sync campaign plans to a governance agent. Plans define authorized parameters: budget, channels, flight dates, markets, policies, delegations.
Uses the governance agent from config.governance.campaign.agent by default. Pass an explicit agent via options.agent to override.
OptionalinputHandler: InputHandlerOptionaloptions: TaskOptions & { agent?: AgentConfig }Get governance audit logs for one or more plans. Returns budget state, channel allocation, per-campaign breakdown, and audit trail.
Uses the governance agent from config.governance.campaign.agent by default. Pass an explicit agent via options.agent to override.
Optionaloptions: TaskOptions & { agent?: AgentConfig }Report a governance outcome for an async task that has resolved.
Use this when a task returned status 'submitted' or 'working' and later resolves via polling or webhooks. The checkId is available on the original TaskResult at result.governance.checkId.
OptionalgovernanceContext: stringOptionalsellerResponse: Record<string, unknown>Optionalerror: { code?: string; message: string }Get AdCP capabilities
Capabilities request parameters
OptionalinputHandler: InputHandlerHandler for clarification requests
Optionaloptions: TaskOptionsTask execution options
Build a creative from a format and brand context
OptionalinputHandler: InputHandlerOptionaloptions: TaskOptionsList accounts
OptionalinputHandler: InputHandlerOptionaloptions: TaskOptionsSync accounts
OptionalinputHandler: InputHandlerOptionaloptions: TaskOptionsSync audiences
OptionalinputHandler: InputHandlerOptionaloptions: TaskOptionsCreate a property list
OptionalinputHandler: InputHandlerOptionaloptions: TaskOptionsGet a property list
OptionalinputHandler: InputHandlerOptionaloptions: TaskOptionsUpdate a property list
OptionalinputHandler: InputHandlerOptionaloptions: TaskOptionsList property lists
OptionalinputHandler: InputHandlerOptionaloptions: TaskOptionsDelete a property list
OptionalinputHandler: InputHandlerOptionaloptions: TaskOptionsList content standards
OptionalinputHandler: InputHandlerOptionaloptions: TaskOptionsGet content standards
OptionalinputHandler: InputHandlerOptionaloptions: TaskOptionsCalibrate content against standards
OptionalinputHandler: InputHandlerOptionaloptions: TaskOptionsValidate content delivery
OptionalinputHandler: InputHandlerOptionaloptions: TaskOptionsGet an SI offering
OptionalinputHandler: InputHandlerOptionaloptions: TaskOptionsInitiate an SI session
OptionalinputHandler: InputHandlerOptionaloptions: TaskOptionsSend a message in an SI session
OptionalinputHandler: InputHandlerOptionaloptions: TaskOptionsTerminate an SI session
OptionalinputHandler: InputHandlerOptionaloptions: TaskOptionsExecute any task by name with type safety
Name of the task to execute
Task parameters
OptionalinputHandler: InputHandlerHandler for clarification requests
Optionaloptions: TaskOptionsTask execution options
Resume a deferred task using its token
Deferred task token
Handler to provide the missing input
Continue an existing conversation with the agent
Message to send to the agent
Conversation context ID to continue
OptionalinputHandler: InputHandlerHandler for any clarification requests
Clear conversation history for a task
Get the agent configuration with normalized protocol
Returns the agent config with:
For guaranteed canonical URL, use getResolvedAgent() instead.
Get the fully resolved agent configuration
This async method ensures the agent config has the canonical URL resolved:
Promise resolving to agent config with canonical URL
Get the agent ID
Get the agent name
Get the agent protocol (may be normalized from original config)
Get the canonical base URL for this agent
Returns the canonical URL if already resolved, or computes it synchronously from the configured URL. For the most accurate canonical URL (especially for A2A where the agent card contains the authoritative URL), use resolveCanonicalUrl() first.
The canonical URL is:
The canonical base URL (synchronous, may not be fully resolved)
Resolve and return the canonical base URL for this agent
This async method ensures the canonical URL is properly resolved:
The result is cached, so subsequent calls are fast.
Promise resolving to the canonical base URL
Check if this agent is the same as another agent
Compares agents by their canonical base URLs. Two agents are considered the same if they have the same canonical URL, regardless of:
Another agent configuration or SingleAgentClient to compare
true if agents have the same canonical URL
Async version of isSameAgent that resolves canonical URLs first
This provides more accurate comparison for A2A agents since it fetches the agent card to get the authoritative canonical URL.
Another agent configuration or SingleAgentClient to compare
Promise resolving to true if agents have the same canonical URL
Get active tasks for this agent
Get detailed information about a specific task
ID of the task to get information for
Promise resolving to task information
Subscribe to task notifications for this agent
Function to call when task status changes
Unsubscribe function
Subscribe to all task events (create, update, complete, error)
Event callbacks for different task events
Unsubscribe function
Register webhook URL for receiving task notifications
URL to receive webhook notifications
OptionaltaskTypes: string[]Optional array of task types to watch (defaults to all)
Unregister webhook notifications
Get comprehensive agent information including name, description, and available tools/skills
Works with both MCP (tools) and A2A (skills) protocols to discover what the agent can do.
Promise resolving to agent information including tools
Get agent capabilities, including AdCP version support
For v3 servers, calls get_adcp_capabilities tool. For v2 servers, builds synthetic capabilities from available tools.
Promise resolving to normalized capabilities object
Detect server AdCP version
'v2' or 'v3' based on server capabilities
Check if server supports a specific AdCP major version
Check if the seller supports a feature.
Feature names resolve as follows:
Absent features return false.
Require that the seller supports all listed features. Throws FeatureUnsupportedError if any are missing.
Call this before making feature-dependent task calls to fail fast with an actionable error message.
Force-refresh cached capabilities from the server. Useful when seller capabilities may have changed.
StaticdiscoverQuery a creative agent to discover available creative formats
This is a static utility method that allows you to query any creative agent (like creative.adcontextprotocol.org) to discover what formats are available before creating a media buy.
URL of the creative agent (e.g., 'https://creative.adcontextprotocol.org/mcp')
Protocol to use ('mcp' or 'a2a'), defaults to 'mcp'
Promise resolving to the list of available formats
// Discover formats from the standard creative agent
const formats = await SingleAgentClient.discoverCreativeFormats(
'https://creative.adcontextprotocol.org/mcp'
);
// Find a specific format
const banner = formats.find(f => f.format_id.id === 'display_300x250_image');
// Use the format in a media buy
await salesAgent.createMediaBuy({
packages: [{
format_ids: [{
agent_url: banner.format_id.agent_url,
id: banner.format_id.id
}]
}]
});
Internal single-agent client implementation
This is an internal implementation detail used by AgentClient and ADCPMultiAgentClient. External users should use AdCPClient (alias for ADCPMultiAgentClient) instead.
Key features: