> ## Documentation Index
> Fetch the complete documentation index at: https://docs.apostra.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Authorizing Apostra in a publisher's adagents.json

> What to put in a publisher's adagents.json so a Storefront Apostra runs is authorized to sell its properties: the authorized_agents entry with url https://interchange.io. What agent_not_listed and the other authorization reasons mean, and how to re-check.

A publisher authorizes your Storefront to sell its inventory in its own `adagents.json` file. Apostra reads that
file for every publisher domain in your coverage and shows the result as the domain's authorization status and
reason. When a domain shows `agent_not_listed`, the file does not name the sales agent Apostra runs for you, and
the publisher has to add one entry. This page says what to put in the publisher's `adagents.json`. Send it to
whoever edits the publisher's file.

Publisher authorization does not prevent transactions. It lets buyers verify that the publisher has authorized
your Storefront to sell its properties. The **Publisher authorization** step in your setup stays open until every
declared domain is authorized.

A Storefront that sells through a platform connection, such as Meta or TikTok, has no publisher authorization
step: its selling rights come from the platform account, not from `adagents.json`.

## Where the file lives

The publisher serves the file at:

```text theme={null}
https://<publisher-domain>/.well-known/adagents.json
```

It must be a valid AdCP `adagents.json` document served over HTTPS. A publisher can instead point to a file
hosted elsewhere, with an `authoritative_location` file at that address or a `MANAGERDOMAIN` line in its
`ads.txt`. The entry then goes in the hosted file, and the properties it selects must belong to the publisher's
domain (see [Which properties count](https://docs.apostra.com/v3/seller-publisher-adagents.md#which-properties-count)).

### How Apostra finds the file

Apostra fetches the publisher's own file first and follows redirects only within the same registrable domain. A
redirect to another registrable domain is refused, and the domain reads as `file_invalid`. Only when the
publisher's own file returns `404` does Apostra read the domain's `ads.txt`, follow its `MANAGERDOMAIN` line one
hop, and use that manager's file instead. A publisher file that exists is used even when it does not authorize
you, so it hides the manager's file until the publisher removes it or points it at the manager's file.

## The entry to add

If your Storefront has an ad-server connection or a modular source, Apostra runs the sales agent that sells it.
The publisher's file must then authorize `https://interchange.io`:

```json theme={null}
{
  "url": "https://interchange.io",
  "authorized_for": "Example News web properties",
  "authorization_type": "property_ids",
  "property_ids": ["examplenews_web"]
}
```

| Field | What to put |
| - | - |
| `url` | `https://interchange.io`, exactly. A trailing slash is fine. |
| `authorized_for` | A short description of what the agent may sell, such as the publisher's name and the properties covered. AdCP requires it; Apostra's check does not read it. |
| `authorization_type` | Which properties the entry covers. See [Authorization types](https://docs.apostra.com/v3/seller-publisher-adagents.md#authorization-types). |
| The selector | The non-empty list that `authorization_type` names: here, `property_ids`. |

This holds even when you also connect a sales agent of your own. While Apostra runs any of your inventory, only
`https://interchange.io` counts for the domain.

### A complete file

The smallest file that authorizes the Storefront declares the property and the entry that selects it:

```json theme={null}
{
  "properties": [
    {
      "property_id": "examplenews_web",
      "property_type": "website",
      "name": "Example News",
      "identifiers": [{ "type": "domain", "value": "examplenews.com" }]
    }
  ],
  "authorized_agents": [
    {
      "url": "https://interchange.io",
      "authorized_for": "Example News web properties",
      "authorization_type": "property_ids",
      "property_ids": ["examplenews_web"]
    }
  ]
}
```

A file that already lists other agents keeps them. Add the entry to `authorized_agents` beside them.

### Common mistakes

These URLs do not match, and leave the domain at `agent_not_listed`:

* `https://interchange.io/mcp` or `https://interchange.io/a2a`. Apostra compares the whole URL, path included.
* `http://interchange.io` or `https://www.interchange.io`.
* The address buyers use to reach your Storefront. That is where buyers send requests, not the agent the
  publisher authorizes.

These leave the domain at a different reason:

* An entry with no `authorization_type`, or with an empty selector, reads as `agent_untyped`.
* A selector that matches none of the publisher's properties, or a `signal_ids` or `signal_tags` entry, reads as
  `agent_not_property_bound`.

## Authorization types

The check accepts the four AdCP property authorization types:

| `authorization_type` | Selector | Covers |
| - | - | - |
| `property_ids` | `property_ids` | The properties in the file whose `property_id` is listed. |
| `property_tags` | `property_tags` | The properties in the file that carry any of the listed tags. |
| `inline_properties` | `properties` | Properties declared inside the entry itself. |
| `publisher_properties` | `publisher_properties` | Properties chosen by publisher domain, such as `{ "publisher_domain": "examplenews.com", "selection_type": "all" }`. |

`signal_ids` and `signal_tags` authorize data signals, not properties, so they do not authorize a Storefront.

### Which properties count

If the file is served from the publisher's own domain, the entry must select at least one property.

If the file is hosted elsewhere, such as a network file reached through `authoritative_location` or
`MANAGERDOMAIN`, the selected properties must belong to the publisher's domain. A property belongs to it when
its `publisher_domain` is that domain, or when it has a `domain` identifier equal to it or a `subdomain`
identifier under it. A `publisher_properties` selector counts when it names the publisher's domain. Apostra
treats `www.example.com` and `example.com` as the same publisher.

## What each reason means

| Reason | What it means | What the publisher does |
| - | - | - |
| `no_file` | No file was found at `/.well-known/adagents.json`, directly or through a pointer. | Publish the file with [the entry](https://docs.apostra.com/v3/seller-publisher-adagents.md#the-entry-to-add). |
| `file_invalid` | A file was found, but it is not a valid `adagents.json` document. | Fix the file so it is valid JSON and matches the AdCP schema. |
| `agent_not_listed` | The file is valid, but no entry's `url` is `https://interchange.io`. | Add [the entry](https://docs.apostra.com/v3/seller-publisher-adagents.md#the-entry-to-add). |
| `agent_untyped` | The entry is there, but has no `authorization_type` with a non-empty selector, as in files written before AdCP 3. | Add `authorization_type` and its selector. |
| `agent_not_property_bound` | The entry is typed, but selects none of this publisher's properties. | Point the selector at the publisher's properties. |

## Re-check after the publisher publishes

Re-check the domain with `refresh` on `save_coverage`:

```json theme={null}
{ "refresh": ["examplenews.com"] }
```

The `refreshed` item shows `authorizationStatus: "authorized"` once the file authorizes your Storefront.
[Re-checking a publisher in your coverage](https://docs.apostra.com/v3/seller-publisher-coverage.md) describes the full response and its
limits.

Apostra also reads the copy of the file held by the
[AgenticAdvertising.org registry](https://agenticadvertising.org), and while that copy predates the fix, the domain
stays unauthorized. So when the publisher's file authorizes you but the registry's copy does not, the re-check asks
the registry to read the file again and waits up to about 15 seconds for its answer. If the registry has not read
the file by then, the re-check still shows `agent_not_listed`. Re-check again in a few minutes.

## If you sell only through your own sales agent

If none of your inventory sources is an ad-server connection or a modular source, and you connect sales agents of
your own, the entry names your agent's URL in place of `https://interchange.io`. Use the URL exactly as you
connected it, path included. An entry for `https://agent.example.com` does not
authorize an agent connected at `https://agent.example.com/mcp`; see
[The publisher file names the URL you connect](https://docs.apostra.com/v3/agent-requirements.md#the-publisher-file-names-the-url-you-connect). If you connect several agents, the publisher can authorize any one of them. A
Storefront with no active inventory source is checked against `https://interchange.io`.

## Related

* [Re-checking a publisher in your coverage](https://docs.apostra.com/v3/seller-publisher-coverage.md) re-reads a publisher's file now.
* [Seller readiness](https://docs.apostra.com/v3/seller-readiness.md) reads whether a setup step is open.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.