---
title: "The ACP-compatible feed of listed doors and their visible actions"
method: GET
path: "/agent/feed.json"
tags: ["discovery"]
---

# The ACP-compatible feed of listed doors and their visible actions

`GET /agent/feed.json`

## Request

- Base URL: `https://api.bubblio.dev`
- URL: `https://api.bubblio.dev/agent/feed.json`
- Auth: none declared

The directory reshaped for agents WITHOUT an MCP client (ChatGPT/Gemini-class
crawlers and feed ingesters): one row per listed door's visible action — an
ask-only door gets one door row — carrying the Agentic Commerce Protocol
product-feed REQUIRED fields (item_id, title, description, brand, url, price,
availability, is_eligible_search, is_eligible_checkout, seller_name, seller_url)
plus `bubblio_*` extension fields pointing at the agent-native MCP path.

These are service actions, not retail SKUs, and the divergences are DECLARED in
the body's `mapping` notes rather than faked: no image_url; availability is
always `in_stock` (a listed action is live — services carry no inventory); free
actions and door rows price at `0.00 USD`; `is_eligible_checkout` is false on
every row because ACP checkout endpoints are not implemented — transacting is
MCP quote→confirm at `bubblio_mcp_url`, where the quote pins the exact price.

Exclusion matches the directory verbatim: unapproved, disabled, and unlisted
doors never appear, hidden (off/orphaned) actions never appear, and no row
carries an identifier that isn't already public in GET /agent/directory.

Cache-friendly by design: the body is rebuilt at most every `ttl_seconds`
(`generated_at` says when; `Cache-Control`/`Age` say so on the wire). A
transient read failure serves an honest empty `items` list — never a 500,
never cached. Per-caller rate-capped; tripping it is a calm 429 with
Retry-After.

## Response `200`

The feed.

- object
  - `kind` 'bubblio-agent-feed', required
  - `version` string, required
  - `generated_at` string, date-time, required
  - `ttl_seconds` integer, required
  - `hub` object, required: The one-connector hub block (the headline path stays MCP).
  - `directory` string, uri, required
  - `docs` string, uri
  - `mapping` string[], required: The honest retail-vocabulary divergences, stated in-band.
  - `items` object[], required
    - `item_id` string, required: `<doorId>:<action>` for action rows; the doorId alone for door rows.
    - `title` string, required
    - `description` string, required
    - `brand` string, required
    - `url` string, uri, required
    - `price` string, required
    - `availability` 'in_stock', required
    - `is_eligible_search` true, required
    - `is_eligible_checkout` false, required
    - `seller_name` string, required
    - `seller_url` string, uri, required
    - `bubblio_door_id` string
    - `bubblio_handle` string
    - `bubblio_mcp_url` string, uri
    - `bubblio_llms_url` string, uri
    - `bubblio_connect_available` boolean: Whether the door's phone-login connect lane is open (a boolean, never the URL).
    - `bubblio_blurb` string
    - `bubblio_action` string: Present on action rows only.
    - `bubblio_action_policy` 'keyed' | 'any'

## Other responses

- `429`: Per-caller cap tripped — calm error body, clamped Retry-After header.

---

[API](https://skmtc.dev/bubblio/apis/bubblio-agent-door-api.md) · [All operations](https://skmtc.dev/bubblio/apis/bubblio-agent-door-api/llms.txt) · [OpenAPI document](https://skmtc.dev/bubblio/apis/bubblio-agent-door-api/revisions/d858aff9c01d?raw)
