Skip to content

feat: emit capabilities envelope status and expose dynamic portfolio hook #867

@bokelley

Description

@bokelley

Summary

Seller applications should not need to monkey-patch PlatformHandler.get_adcp_capabilities() to emit a spec-compliant AdCP v3 capabilities response.

Prebid Sales Agent currently carries a local patch for two things:

  1. Add top-level envelope status: "completed" when the SDK capabilities handler omits it.
  2. Add tenant-specific portfolio.publisher_domains because the SDK capabilities path does not expose a clean per-request/per-tenant portfolio hook.

The first item should be native SDK behavior. The second may need an extension point rather than SDK-owned data access, but it should not require replacing the SDK handler method.

Current local workaround

Sales Agent imports a side-effect module that monkey-patches:

adcp.decisioning.handler.PlatformHandler.get_adcp_capabilities

The patch:

  • Calls the original SDK handler.
  • Adds status: "completed" if missing.
  • Looks up current tenant publisher domains and adds:
{
  "portfolio": {
    "publisher_domains": ["example.com"]
  }
}

This works, but it is fragile because it depends on SDK internals and has to be installed via import side effect.

Expected SDK behavior

The SDK/server layer should:

  • Always emit a protocol-envelope status field for get_adcp_capabilities responses when serving AdCP v3.
  • Preserve existing major_versions and supported_versions behavior.
  • Provide an adopter-owned extension point for dynamic capabilities fields, especially portfolio.publisher_domains, with request context available so sellers can resolve tenant-specific data.

Possible shape:

async def get_adcp_capabilities_extra(context: RequestContext) -> dict[str, Any]:
    return {
        "portfolio": {
            "publisher_domains": [...]
        }
    }

The exact API does not matter as much as the property that seller code should compose with the SDK capabilities handler, not monkey-patch it.

Why this matters

Capabilities discovery is the first interoperability surface for buyers and storyboards. If the SDK emits a response missing the protocol envelope status, adopter apps either fail schema checks or carry local handler patches. If tenant-specific portfolio data has no first-class hook, every multi-tenant seller has to invent its own patch point.

Moving this upstream keeps SDK behavior consistent and keeps seller applications out of SDK internals.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions