> ## 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.

# Built for Agents

> AI-first advertising API designed for seamless agent integration via MCP and REST API

Apostra API is built from the ground up for AI agents. REST and MCP share
the authenticated customer context and converge on canonical services; MCP tools
reuse REST operation schemas where that contract applies. Each MCP version then
presents capabilities in a tool shape suited to its lifecycle: stable V2 persona
connectors and an account-resolved V3 preview.

## Why agent-first

<CardGroup cols={2}>
  <Card title="Shared contracts" icon="layer-group">
    REST routes, named operations, and MCP tools converge on canonical services,
    reusing schemas and authorization checks where their contracts overlap.
    Automated parity gates catch drift. See
    [Philosophy](/v2/concepts/philosophy) for the SESOFI pattern (Single
    Endpoint, Single Object, Full Intent) that keeps composite intents legible.
  </Card>

  <Card title="Versioned agent surfaces" icon="wand-magic-sparkles">
    V2 retains broad generic dispatch for compatibility and adds typed tools for
    high-value work. The V3 preview uses one account-resolved endpoint with
    noun-shaped reads and typed writes.
  </Card>

  <Card title="Declarative tool surface" icon="book">
    V2 skill files and `ask_about_capability` teach the broad operation surface
    on demand. V3 uses bounded `search` and `get` reads plus explicit noun
    schemas, so agents do not have to memorize routes.
  </Card>

  <Card title="Role and account aware" icon="user-tag">
    V2 buyer and storefront URLs are persona-scoped. V3 resolves its catalog
    from the authenticated account and keeps navigation available when the
    account is outside the preview cohort.
  </Card>
</CardGroup>

## Supported AI agents

* **Claude** (Claude.ai Team/Enterprise, Claude Desktop, Claude Code)
* **ChatGPT** (MCP Connectors and Custom GPTs)
* **Microsoft Copilot Studio**
* **Google Gemini Enterprise**
* **Cursor**
* **Custom agents** — anything that speaks MCP or HTTP

Per-agent setup details are below; the [Quickstart](/v2/quickstart) is a one-page index that links here.

## Connection Methods

There are two ways to connect, and they reach the same platform:

* **Connect an AI assistant (MCP)** — use Claude, ChatGPT, another MCP host, or
  an agent you built. You describe what you want in plain language and the
  assistant makes the calls for you. Best when you want a helper that decides
  things and you don't want to write code.
* **Call the API directly (REST)** — your own code calls our REST endpoints
  with a user API key or M2M credentials. Best when you want something exact,
  repeatable, and automated on your own servers.

Both reach the same platform and the same underlying services, but they are not
identical surfaces. The MCP tool catalog varies by version, account, and
enrollment (see [Available MCP Tools](#available-mcp-tools)), and not every REST
operation is exposed as an agent tool. Pick the method that fits how you want to
work, then confirm the specific operations you need are available on it.

### Buyer-agent credential administration

A directly authenticated WorkOS organization administrator can issue an
identity-only WorkOS M2M credential or register an active, organization-owned
or issued, never-before-bound API key or M2M client as a distinct buyer-agent
identity. An issued credential authenticates the automation but carries no
advertiser, account, spend, payment, Terms, or other action permissions. Keep
its one-time client secret secure: it is never shown again. An API key that has
already lazily resolved to the organization operator cannot be reclassified;
use a distinct eligible credential. A WorkOS M2M client-secret rotation keeps
the same client subject and identity and does not use this API.

An API-key replacement preserves an agent identity only when the service
verifies the same customer workload lineage and direct predecessor. Replacing
an issued M2M client is similarly limited to the issuer's server-recorded
workload lineage; organization ownership or an administrator assertion cannot
move an identity. A registered credential cannot move to another principal or
be replayed after retirement. Revocation permanently disables and archives that
credential for Apostra authentication, stops every integration using it,
and cannot be undone by re-registration. The principal is suspended only after
its final active binding is revoked.
These administration endpoints use the shared API v2 base URL
`https://api.apostra.com/api/v2`, rather than the Buyer Base URL in the
table below.
Domain-signed Agents stay on their protocol-native verification and
materialization path rather than using this administration API.

### REST API

Standard HTTP REST API for traditional integrations:

| Environment | Buyer Base URL                         | Storefront Base URL                         |
| ----------- | -------------------------------------- | ------------------------------------------- |
| Production  | `https://api.apostra.com/api/v2/buyer` | `https://api.apostra.com/api/v2/storefront` |

### MCP (Model Context Protocol)

For AI agent integrations using JSON-RPC 2.0:

| Environment | Buyer MCP Endpoint                  | Storefront management MCP                | Canonical Storefront Agent URL |
| ----------- | ----------------------------------- | ---------------------------------------- | ------------------------------ |
| Production  | `https://api.apostra.com/mcp/buyer` | `https://api.apostra.com/mcp/storefront` | `https://interchange.io`       |

<Info>
  The REST URLs are **pinned to v2** and will keep serving v2 even after a
  future major version ships. The buyer and storefront-management MCP URLs are
  **unversioned aliases** that auto-redirect to whatever is currently stable
  (today: v2). The canonical storefront agent URL is an identity publishers list
  in `adagents.json`; it is not the operator's management connector. See
  [Versioning](/v2/authentication#versioning) for when to use each.
</Info>

The limited [V3 Agent Surface preview](/v2/setup/v3-preview) uses
`https://api.interchange.io/mcp/v3`. It is account-resolved and does not replace
the stable V2 connectors.

#### Connection lifetime

A single MCP connection is held open for at most **30 minutes**, after which the
server closes it. This is a limit on one connection, not on your session: your
session id stays valid, and reconnecting with it resumes where you left off.
Well-behaved MCP clients — Claude, ChatGPT, Cursor — reconnect on their own, so
in normal use you will not notice this.

<Warning>
  The same 30-minute limit applies to a **single tool call**. A call that has not
  returned within 30 minutes is cut off and its result is lost — reconnecting
  cannot recover it, because the result was never produced. Long-running work
  such as product discovery against a slow sales agent should be issued as an
  asynchronous operation and polled, rather than awaited on one open call.
</Warning>

Connections also close when we deploy. That is routine, it happens several times
a day, and it is handled the same way: reconnect with your existing session id.

A deploy does wait for in-flight tool calls to finish before closing them — but
only for about three and a half minutes. A call still running when that window
closes is cut off and loses its result, exactly as if it had hit the 30-minute
limit. Because deploys happen several times a day, a call you expect to take
minutes is materially more likely to be interrupted than a fast one. That is the
strongest reason to run long work as an asynchronous operation and poll it,
rather than holding one call open and hoping.

### Available MCP Tools

The exact catalog comes from `tools/list` and can vary by version, account, and
enrollment. Use this table to choose the contract; do not assume every endpoint
always exposes exactly three tools.

| Connector           | Tool model                                                                              | Discovery and execution                                                                                                                                   |
| ------------------- | --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| V2 buyer/storefront | Generic compatibility tools plus registered typed, workflow, and MCP App tools          | `ask_about_capability` discovers broad V2 operations; `api_call` covers the compatibility tail; typed tools carry exact schemas for enrolled capabilities |
| V3 preview          | Shared reads/navigation plus typed `save_<noun>` writes and bounded domain verbs        | Start with `get_status`; use `search`/`get`, `open_page`, and the account's typed nouns                                                                   |
| V2 buyer/storefront | Includes the conversational `ask_murph` entry point; account enablement gates execution | Use it for guidance and support; use the connector's operational tools for deterministic reads and writes                                                 |

V2 generic dispatch remains supported, but a newly published REST route is not
implicitly agent-callable: operation registries, schemas, authorization, and
surface-sync gates make that decision explicit.

### Automating storefront setup

A storefront operator can connect Claude Code, Codex, Cursor, or another MCP
client to:

```
https://api.apostra.com/mcp/storefront
```

Authenticate as a user or API key on the storefront account. The connector can
use `ask_about_capability` to discover setup and product operations, then
`api_call` to read or change the same storefront resources available over REST.
For example, it can inspect inventory, draft and bulk-create products from an
attached spreadsheet, configure buyer routing, and check readiness. Mutating
operations retain the same authorization and confirmation requirements as the
rest of Apostra.

For Codex, register the HTTP connector and complete its OAuth login:

```bash theme={null}
codex mcp add interchange-storefront --url https://api.apostra.com/mcp/storefront
codex mcp login interchange-storefront
```

For headless automation, set an API key in an environment variable and register
it with `--bearer-token-env-var` instead of putting the key in shell history.

This operator connector is separate from the buyer-facing AdCP endpoint at
`https://<seller-cname>/adcp/mcp`, with
`https://api.apostra.com/seller/{platformId}/mcp` as the shared-host
fallback. A hosted Seller exposes that endpoint when
it is configured to advertise as an agent. An external buyer agent authenticates
with entitled Apostra buyer credentials; there is no separate seller-side
connection handshake. Submitted media buys follow the Seller Account's media-buy
approval mode and acceptance policy, including any configured per-buyer
auto-approval. See [Approvals](/v2/storefront/approvals/overview).

Both endpoints also expose a conversational assistant tool when it is enabled for your account:

| Tool        | Purpose                                                                                                                                                                 |
| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ask_murph` | Ask **Murph**, your AI guide to Apostra, a plain-English question — "how do I…", "why is my campaign in this state", "what changed recently" — or file a support report |

<Note>
  `ask_murph` is available once the assistant is enabled for your account. If it
  is not yet turned on, the call returns a friendly "not enabled" message
  instead of an answer — contact Apostra support to enable it. Use
  `ask_murph` for guidance and support, and the connector's operational tools
  for deterministic reads and mutations.
</Note>

## Connecting AI Agents

### Claude Connector (Claude.ai Team / Enterprise)

<Info>
  This is the recommended way to connect Claude to Apostra. It provides
  OAuth-based authentication and works across both Claude.ai (browser) and
  Claude Desktop automatically.
</Info>

**Admin Setup (one-time):**

1. Go to [claude.ai](https://claude.ai) → **Admin Settings** → **Integrations** → **MCP Connectors**
2. Click **Add Connector**
3. Enter the MCP endpoint URL: `https://api.apostra.com/mcp/buyer`
4. Name it (e.g., "Apostra API")
5. Save the connector — it is now available to all members in your organization

**User Setup:**

1. Go to [claude.ai](https://claude.ai) → **Settings** → **Integrations** → **MCP Connectors**
2. Find Apostra connector and click **Connect**
3. Log in with your Apostra credentials when prompted (OAuth)
4. Start chatting! Ask Claude: *"List my advertisers"* or *"Create a performance campaign"*

<Tip>
  Once connected via the connector, it works in both Claude.ai (browser) and
  Claude Desktop. No separate configuration needed.
</Tip>

### Claude Desktop (Personal / Manual Setup)

If you don't have a Claude Team or Enterprise plan, you can connect Claude Desktop directly via OAuth. Edit your Claude Desktop config file:

* **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
* **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`

```json theme={null}
{
  "mcpServers": {
    "apostra-buyer": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://api.apostra.com/mcp/buyer"]
    }
  }
}
```

Restart Claude Desktop. The first call opens a browser for you to sign in to Apostra — `mcp-remote` caches the OAuth token afterward.

If you need to use an API key instead (CI, headless environments), pass it as a header:

```json theme={null}
{
  "mcpServers": {
    "apostra-buyer": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://api.apostra.com/mcp/buyer",
        "--header",
        "Authorization: Bearer scope3_your_api_key_here"
      ]
    }
  }
}
```

### Claude Code (CLI)

OAuth (recommended — no key to manage):

```bash theme={null}
claude mcp add --transport http apostra-buyer https://api.apostra.com/mcp/buyer
claude
```

The first call to the server opens a browser to sign in to Apostra. Claude Code caches the token after that.

API key (CI, headless, or if you can't open a browser): pass the header on registration. Claude Code's HTTP transport doesn't read environment variables, so the API key must be set as a header here.

```bash theme={null}
claude mcp add --transport http apostra-buyer https://api.apostra.com/mcp/buyer \
  --header "Authorization: Bearer scope3_your_api_key_here"
claude
```

Then ask: *"Use ask\_about\_capability to learn how to list advertisers, then use api\_call to list them"*

Once connected, Claude Code can also talk to **Murph** directly through the same server — no extra setup. Just ask a question in plain English and Claude Code will call the `ask_murph` tool:

```text theme={null}
Ask Murph why my campaign is still in PENDING
```

```text theme={null}
Ask Murph how to register credentials for a sales agent
```

Murph keeps its own conversation thread (returned as `conversationUid` in the tool result); follow-up questions in the same Claude Code session continue that thread. `ask_murph` is for guidance and support — for actual reads or mutations, Claude Code uses `api_call`.

### ChatGPT

<Warning>
  **Important:** ChatGPT MCP connectors use OAuth authentication only. Custom
  headers like `x-scope3-api-key` are not supported. Authentication is handled
  automatically through the OAuth login flow.
</Warning>

<Tabs>
  <Tab title="MCP Connector">
    **Connect ChatGPT to Apostra via MCP:**

    1. Go to ChatGPT → **Settings** → **MCP Connectors**
    2. Click **Add Connector**
    3. Enter MCP Server URL: `https://api.apostra.com/mcp/buyer`
    4. Select **OAuth** as the authentication method
    5. Complete Apostra login flow when prompted
    6. Once connected, you'll have access to 3 tools:
       * `health` - Check API status
       * `ask_about_capability` - Learn about available endpoints
       * `api_call` - Make authenticated API calls
    7. Test with: *"Use ask\_about\_capability to learn how to list advertisers"*
  </Tab>

  <Tab title="Custom GPT">
    **Create a Custom GPT with OAuth:**

    1. Go to [ChatGPT](https://chat.openai.com) → **My GPTs** → **Create a GPT**
    2. Go to **Configure** → **Actions** → **Create new action**
    3. Import the OpenAPI spec:
       * Click **Import from URL**
       * Enter: `https://api.apostra.com/api/v2/buyer/openapi.yaml`
    4. Set up OAuth authentication:
       * **Authentication type**: OAuth
       * **Client ID**: Register the redirect URI ChatGPT shows for your action through `/auth/register`, then paste the returned `client_id`.
       * **Authorization URL**: `https://api.apostra.com/authorize`
       * **Token URL**: `https://api.apostra.com/auth/token`
       * **Scope**: `openid profile email`
    5. Save and test with: *"List all my advertisers"*
  </Tab>
</Tabs>

### Custom browser agents

If your agent runs in a browser you control, configure two separate allowlists. They solve different problems and the values are intentionally different:

| Setting            | What to register                                                                            | Why                                                                                                                        |
| ------------------ | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| OAuth redirect URI | The full callback URL, including path, for example `https://mcp.example.com/oauth/callback` | OAuth sends the user back here after login. The callback must match exactly.                                               |
| Browser origin     | The exact origin only, for example `https://mcp.example.com`                                | CORS allows browser calls from this origin to MCP/OAuth endpoints. Do not include paths, queries, fragments, or wildcards. |

#### 1. Register the OAuth redirect URI

Register OAuth redirect URIs with dynamic client registration:

```bash theme={null}
curl -X POST https://api.apostra.com/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "client_name": "Example Agent",
    "redirect_uris": ["https://mcp.example.com/oauth/callback"]
  }'
```

The response includes a generated `client_id`. Use that `client_id` when starting OAuth. Register every callback URL your agent will use, including the path; `https://mcp.example.com/oauth/callback` and `https://mcp.example.com/callback` are different redirect URIs.

Redirect URI rules:

* Production redirect URIs must use `https://`.
* Local development callbacks may use localhost redirect URIs.
* Redirect URIs must not include fragments (`#...`) or embedded usernames/passwords.
* Dynamic registration creates a public OAuth client for PKCE (`token_endpoint_auth_method: "none"`). Do not treat the generated `client_id` as a secret.
* Registering a redirect URI does not by itself authorize a browser agent for an account. For self-serve clients, Apostra issues an authorization code only when the redirect origin has also been approved for the authenticated account.

#### 2. Add the browser origin for CORS

<Note>
  If your custom agent shows *"An account admin must add this browser origin
  before authorizing this MCP client,"* an account admin needs to register that
  origin here first.
</Note>

Seller account admins can add, view, and remove browser origins from
**Apostra → Settings → Discovery & distribution → Browser apps**. Buyer
account admins use **Apostra → Settings → API keys → Browser origins**.
Both account types can also manage them programmatically.

Through the shared v2 API:

```bash theme={null}
curl -X POST https://api.apostra.com/api/v2/browser-origins \
  -H "Authorization: Bearer scope3_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "origin": "https://mcp.example.com",
    "label": "Example Agent"
  }'
```

You can also manage these origins through MCP by asking an authenticated agent to call `list_browser_origins`, `create_browser_origin`, or `delete_browser_origin`. Only account admins can list, create, or delete origins.

Browser origin rules:

* Register only the origin: `scheme://host[:port]`.
* Origins must use `https://`.
* Do not include paths, query strings, fragments, or wildcards.
* Register each environment separately, for example production and staging agent hosts.

#### Security posture

Account-managed browser origins are exact-match and only apply to these browser MCP/OAuth paths: `/authorize`, `/auth/register`, `/auth/token`, `/auth/mcp/authorize`, `/.well-known/*`, `/mcp`, and `/mcp/*`. They do **not** open the full REST API to that origin.

Dynamic client registration is public so MCP clients can discover and register themselves, but account access is still gated by login, PKCE, exact redirect URI matching, and the account-approved browser origin check.

Account-managed origins also do **not** receive credentialed cookie CORS. Apostra returns `Access-Control-Allow-Origin` for allowed MCP/OAuth browser calls, but it does not return `Access-Control-Allow-Credentials` for account-managed origins. Browser agents should use OAuth access tokens or explicit bearer tokens, not Apostra UI cookies. First-party Apostra UI origins continue to use credentialed CORS.

If a browser request is blocked:

1. Confirm the OAuth redirect URI is the full callback URL and was registered through `/auth/register`.
2. Confirm the browser origin is only the origin and was added by an account admin.
3. Confirm the request is going to one of the supported browser MCP/OAuth paths, not an arbitrary REST endpoint.
4. Confirm the browser request does not require cookies or `credentials: "include"`.

### Microsoft Copilot Studio

A maker can add Apostra as a Model Context Protocol tool directly in
Copilot Studio — no Microsoft review required. See
[Connect Apostra to Microsoft Copilot Studio](/v2/reference/connect-copilot-studio)
for the full walkthrough, including the OAuth setup and the manual
client-registration fallback if Copilot Studio's wizard doesn't complete
dynamic client registration automatically.

### Google Gemini Enterprise

A Gemini Enterprise admin can add Apostra as a Connected App — this is a
tenant-admin action with no review from Google. See
[Connect Apostra to Gemini Enterprise](/v2/reference/connect-gemini-enterprise)
for the admin console fields (server URL, authorization URL, token URL,
scopes) and the 100-enabled-actions cap.

### Cursor

**Configure Cursor with Apostra MCP server:**

1. Open Cursor Settings → **MCP** tab
2. Add a new MCP server:
   * **Name**: `apostra`
   * **URL**: `https://api.apostra.com/mcp/buyer`
   * **Headers**: `Authorization: Bearer your-api-key`
3. Restart Cursor
4. In chat, ask: *"Use Apostra tools to list advertisers"*

## What the server tells your agent on connect

Every MCP session starts with operating instructions the server sends during the
handshake. Your agent receives them automatically — nothing to configure — and
they are the same rules our own assistant follows. Knowing what is in them tells
you what behaviour to expect, and what to preserve if you wrap our tools in your
own harness.

For a **storefront** connection:

**Orient before acting.** Call `get_storefront_readiness` for the current
configuration state and what is blocking the storefront from transacting, rather
than reconstructing it from a series of list calls.

**Look up the operation before calling it.** `api_call` takes a named
`operation`; there is no raw method-and-endpoint mode, and an invented name is
rejected. Call `ask_about_capability` first for the exact operation name and
field shapes. Prefer a typed tool where one exists.

**Route explanation to Murph.** "How do I…", "why is my X stuck in state Y",
"what changed recently" and "I think this is broken" go to `ask_murph`, which
searches the published documentation, inspects live storefront state, and can
file an internal report. Murph is read-only; mutations stay on `api_call` or a
typed tool.

**One mutating call per turn.** Make one write, present the result, then stop and
wait for the user.

**Verify success before reporting it.** A call succeeded only if the status is
2xx *and* the payload carries the endpoint's success indicator — a returned id,
the updated resource, an empty 204. A `202` means queued, not done: report it as
kicked off and surface the operation id. If the indicator is missing or
contradicts success, surface the error verbatim and do not say the change was
made.

**Do not answer publisher authorization from memory.** Whether a domain needs an
`adagents.json` entry, and what belongs in it, depends on how that inventory is
sold. Look it up through Murph or the published documentation, or read live state
via `open_property_roster` — see [Identity
documents](/v2/concepts/identity-documents).

**State only what the data shows.** If a tool returns no results, say so rather
than speculating about why. Never claim a connection, authorization, or status
exists unless a tool response contains it.

## Authentication

Use **OAuth** for Claude/ChatGPT MCP connectors (handled automatically) or an **API key** (`Authorization: Bearer scope3_...`) for CLIs, Cursor, and custom agents. See [Authentication](/v2/authentication) for full details.

## Notifications

The API surfaces unread notifications inline in `ask_about_capability` responses, so agents can proactively flag campaign or creative issues to users. See the [Notifications guide](/v2/guides/notifications) for setup and the REST endpoints.

## Next Steps

<CardGroup cols={2}>
  <Card title="Quickstart" href="/v2/quickstart" icon="rocket">
    Connect Claude, ChatGPT, Cursor, or a custom agent in minutes.
  </Card>

  <Card title="Buyer Onboarding" href="/v2/setup/buyer-onboarding" icon="user-plus">
    The end-to-end campaign-launch journey for buyer integrations.
  </Card>

  <Card title="Skill" href="/v2/skill" icon="book">
    What `skill.md` is and how agents use it for capability discovery.
  </Card>

  <Card title="Authentication" href="/v2/authentication" icon="key">
    API keys, OAuth, and SSO configuration.
  </Card>
</CardGroup>
