Skip to main content
The v2 API is in active development. The onboarding flow described here may evolve before general availability.

Overview

A storefront is the seller-side surface in the Scope3 marketplace. It represents your brand, the inventory sources you offer through agentic protocols, and the billing relationship that lets buyer agents transact with you. The seller journey has four user-visible steps, mirroring the in-app onboarding UI:
  1. Verify your company — resolve your brand from the AAO registry, set your operator domain, and auto-verify (or fall back to manual KYC).
  2. Add agents — register one or more inventory sources, each backed by an ADCP-compatible agent. AAO compliance is gated here.
  3. Set up billing (optional) — connect Stripe to receive payouts. Not required for activation.
  4. Go live — confirm readiness and flip the storefront to ACTIVE.
A few helper endpoints support these steps but are not standalone “steps”:
  • POST /resolve-brand — looks up your brand in the AAO registry. Used inside Step 1 to pre-fill the form.
  • GET /discover-agents — surfaces agents AAO knows about for your domain. Used inside Step 2.
  • GET /readiness — a status query you can call any time to see what gates remain. Surfaced in Step 4 (and re-run server-side at activation).
Each customer has one storefront. There is no customerId path parameter — the storefront is resolved from your API key’s customer context.

Who this is for

  • Publishers and sales houses connecting their inventory to agentic buyers
  • Retail media networks exposing on-site or off-site inventory through ADCP-compatible agents
  • Any seller who wants buyer agents (e.g. Scope3, Claude, custom buyers) to be able to discover and transact against their inventory

Prerequisites

1

Scope3 API key

Generate a key at agentic.scope3.com/user-api-keys. Keys start with scope3_ and authorize all storefront endpoints.
2

A registered brand on AAO

Your brand should have a brand.json published and resolvable through the AAO registry at agenticadvertising.org. If you don’t have one yet, the resolve-brand call returns a builderUrl that points you to the registry’s brand builder.
3

At least one ADCP-compatible agent

A SALES, SIGNAL, CREATIVE, or OUTCOME agent reachable over MCP or A2A. You’ll need its endpoint URL, protocol, and (for non-OAuth agents) auth credentials.
4

Optional: Stripe account

Required only if you want Scope3 to settle payments through your storefront. Stripe Connect provisioning is gated to non-child customer accounts.

Onboarding flow

1

Verify your company

The first thing a seller does is identify their company so Scope3 can pull their brand profile from AAO and validate the operator domain. This step combines a brand lookup, a storefront update, and an automatic operator-domain verification check.

1. Resolve your brand (helper)

Look up your brand in the AAO registry to grab the canonical brand name and logo URL. This call has no side effects — it’s only used to populate the storefront update payload.
curl -X POST https://api.agentic.scope3.com/api/storefront/resolve-brand \
  -H "Authorization: Bearer scope3_..." \
  -H "Content-Type: application/json" \
  -d '{ "domain": "acme.com" }'
Response (resolved)
{
  "resolved": true,
  "domain": "acme.com",
  "brandName": "Acme",
  "logoUrl": "https://cdn.example.com/acme-logo.svg",
  "manifestUrl": "https://acme.com/.well-known/brand.json",
  "manifest": { "...": "full brand.json" },
  "registryEntry": { "...": "AAO registry entry" },
  "authorizedOperators": [
    { "domain": "acme-media.com", "scope": "primary" }
  ],
  "houseBrand": false
}
If no manifest is found, the call returns 200 with { "resolved": false, "builderUrl": "https://agenticadvertising.org/brand" } — point the operator at the builder URL to publish a brand.json.
The domain field is validated against a strict FQDN regex. IP addresses and internal hostnames are rejected to prevent SSRF.

2. Write the brand fields onto your storefront

If your customer doesn’t yet have a storefront record, create one first:
curl -X POST https://api.agentic.scope3.com/api/storefront \
  -H "Authorization: Bearer scope3_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Media",
    "publisherDomain": "acme.com",
    "plan": "basic"
  }'
POST /storefront is idempotent — if a storefront already exists for your customer, the existing record is returned instead of creating a duplicate.Then update it with the brand fields from resolve-brand plus your operator domain:
curl -X PUT https://api.agentic.scope3.com/api/storefront \
  -H "Authorization: Bearer scope3_..." \
  -H "Content-Type: application/json" \
  -d '{
    "operatorDomain": "scope3.com",
    "brandName": "Acme",
    "logoUrl": "https://cdn.example.com/acme-logo.svg"
  }'
Response
{
  "platformId": "acme-media",
  "name": "Acme Media",
  "publisherDomain": "acme.com",
  "operatorDomain": "scope3.com",
  "brandName": "Acme",
  "logoUrl": "https://cdn.example.com/acme-logo.svg",
  "operatorDomainVerified": true,
  "plan": "basic",
  "status": "PENDING",
  "createdAt": "2026-04-25T12:00:00.000Z",
  "updatedAt": "2026-04-25T12:00:00.000Z"
}
When you set operatorDomain, the API automatically compares it against your customer’s registered customerDomain (and your parent customer’s, if applicable). If they match, operatorDomainVerified flips to true immediately. Otherwise a verification request is sent to Scope3 staff and you’ll need a manual KYC review.The flag is recomputed only when the operator domain actually changes — manual superadmin verifications are preserved across unrelated edits.
Updatable fields on PUT /storefront: name, publisherDomain, plan, status, operatorDomain, brandName, logoUrl. At least one field must be provided.
2

Add agents (inventory sources)

An inventory source binds a named slot inside your storefront to an ADCP-compatible agent. Buyer-side discovery surfaces sources, and media buys flow through the agent attached to each one.

1. Discover agents (helper)

Optional but recommended: see what AAO already knows about your domain. This proxies AAO’s operator and publisher endpoints plus your .well-known/adagents.json.
curl "https://api.agentic.scope3.com/api/storefront/discover-agents?domain=acme.com" \
  -H "Authorization: Bearer scope3_..." \
  -H "x-aao-api-key: aao_..."
The x-aao-api-key header is optional. Without it you only get the public registry view. Pass it to also surface storyboard compliance status for agents you operate.
Response
{
  "domain": "acme.com",
  "operator": {
    "domain": "acme.com",
    "member": { "slug": "acme-media", "display_name": "Acme Media" },
    "agents": [
      {
        "url": "https://agent.acme-media.com/mcp",
        "name": "Acme Media Sales",
        "type": "SALES",
        "compliance": {
          "status": "passing",
          "storyboards_passing": 12,
          "storyboards_total": 12,
          "headline": "All scenarios pass"
        }
      }
    ]
  },
  "publisher": {
    "domain": "acme.com",
    "adagents_valid": true,
    "properties": [ { "id": "acme-app", "type": "mobile_app", "name": "Acme App" } ],
    "authorized_agents": [
      { "url": "https://agent.acme-media.com/mcp", "authorized_for": ["display"] }
    ]
  }
}
Responses are cached server-side for 2 minutes per (domain, key fingerprint). Pass &refresh=true to force a re-fetch.

2. Register an inventory source

curl -X POST https://api.agentic.scope3.com/api/storefront/inventory-sources \
  -H "Authorization: Bearer scope3_..." \
  -H "Content-Type: application/json" \
  -d '{
    "sourceId": "acme-sales",
    "name": "Acme Media Sales",
    "executionType": "agent",
    "type": "SALES",
    "endpointUrl": "https://agent.acme-media.com/mcp",
    "protocol": "MCP",
    "authenticationType": "API_KEY",
    "auth": { "type": "bearer", "token": "agent_abc123..." },
    "description": "Primary sales agent for Acme on-site display + CTV"
  }'
Required when executionType: "agent": type, endpointUrl, protocol, authenticationType. auth is required for API_KEY and JWT agents and must be omitted for OAUTH and NO_AUTH.
Inventory-source credentials (API keys and JWT private keys) are stored in Google Secret Manager and only referenced by an opaque auth_secret_ref in the database. They are never echoed back in API responses (the response surfaces authConfigured: true instead). Never log, screenshot, or commit raw credentials to source control. Rotate immediately if a credential is exposed.
{
  "authenticationType": "API_KEY",
  "auth": { "type": "bearer", "token": "agent_abc123..." }
}
Token formats bearer, apikey, and api_key are all accepted. The token is stored in Google Secret Manager and never echoed back. The source goes to pending and auto-activates once the agent is reachable with the credential.
Response
{
  "sourceId": "acme-sales",
  "name": "Acme Media Sales",
  "executionType": "agent",
  "executionConfig": null,
  "status": "pending",
  "agentId": "agent_01HX...",
  "type": "SALES",
  "endpointUrl": "https://agent.acme-media.com/mcp",
  "protocol": "MCP",
  "authenticationType": "API_KEY",
  "authConfigured": true,
  "createdAt": "2026-04-25T12:05:00.000Z",
  "updatedAt": "2026-04-25T12:05:00.000Z"
}
Before creating a source, the API checks the agent’s compliance status with AAO. The check returns one of:
  • passing — proceed.
  • pending — proceed (logged but not blocked).
  • not-passing — request is rejected with VALIDATION_ERROR.
  • not-registered — agent must be registered with AAO first.
If AAO is unreachable the request fails with SERVICE_UNAVAILABLE — retry once it recovers. Superadmins can bypass this gate; bypassed sources include complianceBypassed: true in the response.
The basic plan currently allows one inventory source per storefront. Updates are partial — PUT /api/storefront/inventory-sources/:sourceId accepts any subset of name, description, endpointUrl, protocol, authenticationType, auth, executionConfig, status. Updating auth rotates the stored credential; omitting it preserves the existing one.
Sources can’t be deleted while their backing agent has non-terminal media buys (ACTIVE, PAUSED, PENDING_APPROVAL, or INPUT_REQUIRED). Cancel or terminate those first.
3

Set up billing (optional)

Stripe Connect lets Scope3 settle payments on your behalf. Billing is not a hard blocker for activation — your storefront can go live and serve impressions without Stripe. The readiness endpoint surfaces billing as informational only.Skip this step entirely if Scope3 is not handling settlement. Child customer accounts always inherit billing from the parent and cannot provision their own.

1. Provision a Connect account

curl -X POST https://api.agentic.scope3.com/api/storefront/billing/connect \
  -H "Authorization: Bearer scope3_..."
Response
{
  "stripeConnectedAccountId": "acct_1Abc...",
  "onboardingUrl": "https://connect.stripe.com/setup/e/acct_1Abc.../..."
}
Redirect the operator to onboardingUrl to complete Stripe’s KYC flow.If the operator drops out mid-onboarding, get a fresh link:
curl https://api.agentic.scope3.com/api/storefront/billing/onboard \
  -H "Authorization: Bearer scope3_..."

3. Check status + balance

curl https://api.agentic.scope3.com/api/storefront/billing/status \
  -H "Authorization: Bearer scope3_..."
Response
{
  "accountId": "acct_1Abc...",
  "chargesEnabled": true,
  "payoutsEnabled": true,
  "requirements": {
    "currentlyDue": [],
    "eventuallyDue": ["external_account"]
  },
  "balance": {
    "available": [{ "amount": 4250000, "currency": "usd" }],
    "pending": [{ "amount": 120000, "currency": "usd" }]
  }
}

Other billing endpoints

EndpointPurpose
GET /api/storefront/billingCurrent platform fee %, additional fees, currency, net days
PUT /api/storefront/billingAdmin-only — update fee config
GET /api/storefront/billing/transactionsCursor-paginated balance transactions
GET /api/storefront/billing/payoutsCursor-paginated payouts
POST /api/storefront/billing/account-sessionEmbedded Stripe Connect session for in-app onboarding UI
GET /api/storefront/billing/accountsParent customers — billing status across child accounts
Parent customers can pass ?targetCustomerId=<childId> on every /api/storefront/billing/* endpoint to operate on a child’s billing. Access is validated against the parent/child relationship before each call.
4

Go live

Activation flips the storefront from PENDING to ACTIVE. Buyer agents can only discover and transact against your inventory once you’re live.

1. Confirm readiness

GET /api/storefront/readiness runs every gate that activation will check server-side. Call it any time during onboarding to see what’s still missing.
curl https://api.agentic.scope3.com/api/storefront/readiness \
  -H "Authorization: Bearer scope3_..."
Response
{
  "platformId": "acme-media",
  "status": "ready",
  "checks": [
    {
      "id": "inventory_sources",
      "name": "Inventory sources",
      "category": "inventory",
      "description": "At least one source has been configured.",
      "status": "complete",
      "isBlocker": true,
      "method": "agent",
      "details": "1 source configured"
    },
    {
      "id": "agent_status",
      "name": "Agent status",
      "category": "agents",
      "description": "All agents are active.",
      "status": "complete",
      "isBlocker": true,
      "details": "1 of 1 agents are active"
    },
    {
      "id": "agent_auth",
      "name": "Agent authentication",
      "category": "agents",
      "description": "All agents have been authenticated.",
      "status": "complete",
      "isBlocker": true,
      "details": "1 of 1 agents are authenticated"
    },
    {
      "id": "billing_setup",
      "name": "Billing",
      "category": "billing",
      "description": "Stripe Connect onboarding complete.",
      "status": "complete",
      "isBlocker": false,
      "details": "Stripe Connect is complete"
    }
  ]
}
  • inventory_sources (blocker) — at least one source must exist.
  • agent_status (blocker) — every agent backing a source must be ACTIVE.
  • agent_auth (blocker) — non-OAuth agents must have a stored credential. OAuth agents are excluded once their token is captured.
  • agent_connectivity (blocker, only on GET /readiness/compliance) — runs the ADCP comply() test suite against each agent in sandbox mode (60s timeout). Returns per-agent track results and observations.
  • billing_setup (informational, NOT a blocker) — Stripe is recommended but not required to activate.
Top-level status is blocked if any check with isBlocker: true is not complete, otherwise ready.For a deeper agent connectivity test (full ADCP compliance scenarios in sandbox mode), hit:
curl https://api.agentic.scope3.com/api/storefront/readiness/compliance \
  -H "Authorization: Bearer scope3_..."
This may take up to 60 seconds.

2. Activate

curl -X PUT https://api.agentic.scope3.com/api/storefront \
  -H "Authorization: Bearer scope3_..." \
  -H "Content-Type: application/json" \
  -d '{ "status": "ACTIVE" }'
The API re-runs readiness server-side before applying the change. If any blocker is still failing, the request is rejected with the failing check descriptions:
Rejection
{
  "error": "VALIDATION_ERROR",
  "message": "Cannot activate storefront: All agents must be active to go live; All agents must be authenticated to go live",
  "field": "status"
}
When activation succeeds, every agent in PENDING status that’s linked through a source is automatically promoted to ACTIVE so buyer traffic can route through it.

Lifecycle states

StatusMeaning
PENDINGCreated but not live. Buyer-side discovery does not surface it.
ACTIVELive. Buyer agents can discover the storefront and transact.
DISABLEDTemporarily off. Existing media buys remain bound but new ones can’t be placed.
Allowed transitions: PENDING ↔ ACTIVE ↔ DISABLED (you can’t go straight from DISABLED to PENDING).

Troubleshooting

This is logged but not a blocker. The source is created and will auto-activate once the agent is reachable. No action required unless the status flips to not-passing.
Visit agenticadvertising.org and check the storyboard test results for your agent URL. Resolve the failing scenarios in your agent implementation, wait for the next test run, then retry source creation.
The agent’s endpointUrl doesn’t appear in the AAO registry at all. Register it through the AAO operator dashboard before retrying.
Your agent record is PENDING. Most often this means the auth credential hasn’t been verified yet. Re-submit the source with a fresh auth block, or for OAuth agents make sure the OAuth callback completed.
A non-OAuth agent has no stored credential. PUT /api/storefront/inventory-sources/:sourceId with an auth block to set one.
Look at the compliance array on the failing check — each entry has per-track failureReason, summary, and observations. The most common causes are auth misconfiguration, schema drift between your agent and the ADCP spec, and agent-side timeouts beyond 60s.
Verification only runs when operatorDomain is being changed. If you set the domain before the customer’s customerDomain was registered, update operatorDomain to the same value again to trigger re-evaluation, or have a Scope3 admin verify manually.
Stripe credentials are missing on the API server. Contact Scope3 support — this is environment config, not a customer-side issue.
Your customer is a child of a parent org. Either provision billing on the parent and inherit, or have the parent call POST /api/storefront/billing/connect?targetCustomerId=<your-id> on your behalf.

Next steps