Developer reference
The feed, checkout sessions, MCP, UCP and the store agent. Everything an agent needs to find products and hand a shopper a checkout.
Base URLhttps://bmos-v3.apps.art-and-see.com
Examples use the live demo store (). Try it calls the real API. Test mode, nothing is charged.
On this page
Start here
Every published store gets the same public surfaces. No key, CORS open, JSON unless noted. Replace STORE_ID with the id in your dashboard under Install.
- Read the catalogGET the feed, or the plain-language
skill.md. - Pick what can be boughtOnly products with
is_eligible_checkout: true. Affiliate items (external: true) are recommend-only. - Hand the shopper a checkoutCreate a checkout session and give the shopper
links.pay, or send a checkout link. They confirm the total and pay on the store's checkout.
Agents that speak MCP can do all three through https://bmos-v3.apps.art-and-see.com/mcp.
Feed JSON
Fields follow the OpenAI Product Feed Spec plus a BMOS checkout block. Feeds are cached for 60 seconds.
curl https://bmos-v3.apps.art-and-see.com/feeds/STORE_ID
Top level
| Field | Type | Present | Example |
|---|---|---|---|
| feed_version | string | Always | "0.2" Version of this spec. |
| generated_at | string (ISO 8601) | Always | "2026-10-01T12:00:00.000Z" When the feed was built. Cached 60 s. |
| merchant.id | string | Always | "STORE_ID" Use it as store_id everywhere else. |
| merchant.name · url · currency | string | Always | "Excalibur Brothers" The store, its own website and ISO 4217 currency. |
| merchant.return_policy · terms_of_service · privacy_policy | string (URL) | null | Nullable | null Set by the merchant in Settings. |
| capabilities.human_checkout | string (URL) | Always | "…/c/STORE_ID" Base of the checkout link. |
| capabilities.agent_checkout | string (URL) | Always | "…/api/checkout_sessions" Checkout sessions endpoint. |
| capabilities.payment_methods | string[] | Always | ["card","apple_pay","google_pay","paypal"]crypto appears when the store has a USDC wallet. |
| capabilities.crypto_rails | string[] | Always | ["base"] Any of base, solana, tempo, coinbase. |
| capabilities.test_mode | boolean | Always | true Nothing is charged while true. |
| products | Product[] | Always | […] Hidden products are left out. |
Product
| Field | Type | Present | Example |
|---|---|---|---|
| id | string | Always | "lJY0B7QjtBV5Uw" Use this in items[].id. |
| item_id | string | Always | "KTN4" Merchant SKU, or id when there is none. Checkout accepts it too. |
| title · description | string | Always | "Kumori Katana" Description is an empty string when missing. |
| link · image_link | string (URL) | Always | "https://…" Product page and main image. Empty string when missing. |
| additional_image_link | string[] | Always | [] Up to 5 more images. |
| price | string | null | Nullable | "1199.97 USD" Amount and currency, always without thousands separators. |
| availability | string | Always | "in_stock" in_stock, out_of_stock or preorder. |
| brand · seller_name | string | Always | "Excalibur Brothers" Brand falls back to the store name. |
| gtin · mpn | string | null | Nullable | null GTIN is 8, 12, 13 or 14 digits. |
| product_category · item_group_id · variant | string | null | Nullable | null |
| is_eligible_search | boolean | Always | true Agents may show it. |
| is_eligible_checkout | boolean | Always | true Only these can be bought here. |
| channels_excluded | string[] | Always | [] Agents this product is hidden from, e.g. ["grok"]. |
| external · external_link | boolean · string | null | Always | falsetrue = sold elsewhere (affiliate). Recommend it, never buy it. |
| checkout | object | null | Nullable | { "type": "bmos_checkout_session", … } Ready request: endpoint, method, body, and human_url for the shopper. null when not buyable. |
skill.md
Plain instructions an agent can follow: where the feed is, what can be bought, how to open a checkout. Markdown.
curl https://bmos-v3.apps.art-and-see.com/feeds/STORE_ID/skill.md
Checkout sessions
States follow the Agentic Checkout spec: not_ready_for_payment → ready_for_payment → completed or canceled. Amounts are in cents.
/api/checkout_sessionsCreate a session from feed ids or SKUs. Returns 201. Items that cannot be bought come back in errors; if none can, 422. agent stamps the order with who sent it.
curl -X POST https://bmos-v3.apps.art-and-see.com/api/checkout_sessions \
-H 'content-type: application/json' \
-d '{"store_id":"STORE_ID","items":[{"id":"PRODUCT_ID","quantity":1}],"agent":"Claude"}'
/api/checkout_sessions/:idStatus, line items, totals, delivery options and links.pay.
curl https://bmos-v3.apps.art-and-see.com/api/checkout_sessions/SESSION_ID
/api/checkout_sessions/:idSet buyer, fulfillment_address, fulfillment_option_id, or replace items. With email and address the status becomes ready_for_payment.
curl -X POST https://bmos-v3.apps.art-and-see.com/api/checkout_sessions/SESSION_ID \
-H 'content-type: application/json' \
-d '{"buyer":{"email":"sam@example.com","name":"Sam Lee"},"fulfillment_address":{"line1":"1 Main St","city":"Austin","state":"TX","zip":"78701","country":"US"},"fulfillment_option_id":"standard"}'
/api/checkout_sessions/:id/completepayment.method: card, applepay, googlepay, paypal or crypto (with payment.rail). Returns status: "completed" and order.id. Test mode: nothing is charged.
curl -X POST https://bmos-v3.apps.art-and-see.com/api/checkout_sessions/SESSION_ID/complete \
-H 'content-type: application/json' \
-d '{"payment":{"method":"card"}}'
/api/checkout_sessions/:id/cancelCancel an unpaid session. A completed session stays completed.
curl -X POST https://bmos-v3.apps.art-and-see.com/api/checkout_sessions/SESSION_ID/cancel
Most agents should not pay for the shopper. Give the shopper links.pay so they confirm the exact total on the store's checkout.
Checkout links
A plain link that opens the store's checkout with the cart filled. It creates a session and redirects (303) to /pay/SESSION_ID. Every buyable product carries its own link in checkout.human_url.
https://bmos-v3.apps.art-and-see.com/c/STORE_ID?items=PRODUCT_ID:1,OTHER_ID:2&from=chatgpt
items is a comma list of id:quantity. from names the agent, for example ChatGPT chatgpt, Claude claude or Muse muse; the order shows it.
MCP server
Streamable HTTP: POST JSON-RPC 2.0 to one endpoint. Four tools, all scoped by store_id.
curl https://bmos-v3.apps.art-and-see.com/mcp
/mcp · initializeProtocol version and server info.
curl -X POST https://bmos-v3.apps.art-and-see.com/mcp \
-H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize"}'
/mcp · tools/listThe four tools with their input schemas.
curl -X POST https://bmos-v3.apps.art-and-see.com/mcp \
-H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
| Tool | Required | Optional | Returns |
|---|---|---|---|
| search_products | store_id, query | max_price | Up to 10 products with price, stock, buyable and buy_url. |
| get_offer | store_id, product_id | — | One product with live price, stock and buy link. |
| ask_store_agent | store_id, message | — | The store's own agent answers from its catalog and policies only. |
| create_checkout | store_id, items | agent | A checkout session. The shopper confirms the total at links.pay. |
/mcp · tools/callCall a tool by name with arguments. Results come as text content and structuredContent.
curl -X POST https://bmos-v3.apps.art-and-see.com/mcp \
-H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"search_products","arguments":{"store_id":"STORE_ID","query":"leather flask gift","max_price":60}}}'
curl -X POST https://bmos-v3.apps.art-and-see.com/mcp \
-H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"get_offer","arguments":{"store_id":"STORE_ID","product_id":"PRODUCT_ID"}}}'
curl -X POST https://bmos-v3.apps.art-and-see.com/mcp \
-H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":5,"method":"tools/call","params":{"name":"ask_store_agent","arguments":{"store_id":"STORE_ID","message":"Do you ship to Canada?"}}}'
curl -X POST https://bmos-v3.apps.art-and-see.com/mcp \
-H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":6,"method":"tools/call","params":{"name":"create_checkout","arguments":{"store_id":"STORE_ID","items":[{"id":"PRODUCT_ID","quantity":1}],"agent":"Claude"}}}'
UCP
Universal Commerce Protocol discovery: services, catalog and checkout capabilities, and the merchant's feed. Pass store to scope it.
curl 'https://bmos-v3.apps.art-and-see.com/.well-known/ucp?store=STORE_ID'
Agent card
An A2A agent card for the store's own agent: skills, transport and the chat endpoint.
curl 'https://bmos-v3.apps.art-and-see.com/.well-known/agent-card.json?store=STORE_ID'
llms.txt
A short plain-text index of the store's agent surfaces. Text, not JSON.
curl 'https://bmos-v3.apps.art-and-see.com/llms.txt?store=STORE_ID'
Store agent chat
Ask the store's own agent. It answers from the live catalog and the merchant's policies and FAQ, and returns product cards. Limited to 20 questions a minute per visitor.
/api/agent/:storeId/chatBody: message (up to 400 characters) and optional origin. Returns reply, products, suggestions and answered.
curl -X POST https://bmos-v3.apps.art-and-see.com/api/agent/STORE_ID/chat \
-H 'content-type: application/json' \
-d '{"message":"A leather flask for a gift, under $60","origin":"widget"}'
Widget
One script tag adds the cart, the checkout and the store agent to the merchant's site. It reads the feed, so prices always match.
<script src="https://bmos-v3.apps.art-and-see.com/widget.js" data-store="STORE_ID" defer></script>
Your own buttons
Mark any button with a feed product id or SKU.
<button data-bmos-add="PRODUCT_ID">Add to cart</button>
window.BMOS.add('PRODUCT_ID', 2); // add 2 and open the cart
window.BMOS.open(); // open the cart
window.BMOS.products; // products the widget loaded
Errors
Errors are JSON { "error": "message" }, written for a person. Show them as they are. MCP errors use JSON-RPC error.code.
| Status | When | Message |
|---|---|---|
| 201 | Session created | May include errors[] for items left out |
| 303 | Checkout link opened | Redirects to /pay/SESSION_ID |
| 404 | Unknown or unpublished store | “Feed not found or not published” · “Unknown or unpublished store” |
| 404 | Unknown session | “Not found” |
| 422 | Nothing in the cart can be bought | “None of the items can be bought here” |
| 422 | Complete before email and address | “Email and delivery address are required before payment” |
| 422 | Crypto without a network | “Pick a crypto network” |
| 429 | Too many chat questions | “Too many questions. Try again in a minute.” |
| 500 | Our side | “Something went wrong on our side. Try again.” |
Test mode
Every store runs in test mode today. Payments are simulated end to end, nothing is charged, and orders are real records in the dashboard. Feeds and sessions say test_mode: true.
Test card 4242 4242 4242 4242, any future date, any 3 digits. Apple Pay, Google Pay, PayPal and USDC are simulated too.