Skip to content

bug : fetch_adagents does not follow authoritative_location redirects per AdCP specification #114

@lclaudon

Description

@lclaudon

Description

The fetch_adagents() function in the adcp library does not handle the authoritative_location redirect pattern defined in the AdCP specification. When a publisher's adagents.json contains only a reference to a centralized file, the library fails with a validation error instead of following the redirect.

Steps to Reproduce

import asyncio
from adcp import fetch_adagents

async def test():
    # capital.fr uses authoritative_location redirect
    data = await fetch_adagents('capital.fr')
    print(data)

asyncio.run(test())

Result:

AdagentsValidationError: adagents.json must have 'authorized_agents' field

Root Cause

The fetch_adagents() function at line 356 immediately checks for authorized_agents field without first checking if the response contains an authoritative_location redirect.

capital.fr/.well-known/adagents.json returns:

{
  "$schema": "https://adcontextprotocol.org/schemas/v2/adagents.json",
  "authoritative_location": "https://creas.prismamediadigital.com/adcp/adagents.json",
  "last_updated": "2025-12-15T10:38:53.435Z"
}

The authoritative location contains the actual data:

{
  "authorized_agents": [...],
  "properties": [...]
}

The library's type system already supports this pattern (see AuthorizedSalesAgents1 vs AuthorizedSalesAgents2 in adcp/types/generated_poc/adagents.py), but the fetch_adagents() function doesn't implement the redirect logic.

Expected Behavior

When fetch_adagents() encounters a response with authoritative_location, it should:

  1. Follow the HTTPS URL specified in authoritative_location
  2. Fetch the adagents.json from that location
  3. Return the resolved data containing authorized_agents

Proposed Fix

Add authoritative_location handling before validating authorized_agents:

# In fetch_adagents(), after parsing JSON:

# Check for authoritative_location redirect
authoritative_location = data.get("authoritative_location")
if authoritative_location and isinstance(authoritative_location, str):
    # Validate HTTPS
    if not authoritative_location.startswith("https://"):
        raise AdagentsValidationError(
            f"authoritative_location must be HTTPS: {authoritative_location}"
        )
    # Follow redirect (with depth limit to prevent loops)
    return await _fetch_from_authoritative_url(authoritative_location, ...)

# Only require authorized_agents if no redirect
if "authorized_agents" not in data:
    raise AdagentsValidationError("adagents.json must have 'authorized_agents' field")

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions