@opencommerceprotocol/spec
v1.0.0
Published
Open Commerce Protocol — JSON Schema definitions and TypeScript types
Maintainers
Readme
@opencommerceprotocol/spec
TypeScript types, JSON schemas, and constants for the Open Commerce Protocol.
Installation
npm install @opencommerceprotocol/specUsage
import { OCPManifest, OCPProduct, OCP_VERSION } from '@opencommerceprotocol/spec';Core Types
OCPManifest
The merchant discovery manifest served at /.well-known/ocp.json.
const manifest: OCPManifest = {
version: '1.0',
merchant: {
name: 'My Store',
url: 'https://mystore.com',
currency: 'USD',
locale: 'en',
logo: 'https://mystore.com/logo.png',
description: 'Quality products for everyone',
contact: '[email protected]',
},
capabilities: {
catalog: true,
search: true,
cart: true,
checkout: 'redirect', // 'full' | 'escalate' | 'redirect' | 'none'
orders: false,
returns: false,
},
discovery: {
feed: 'https://mystore.com/ocp/products.jsonl',
feed_format: 'jsonl',
feed_updated: '2026-03-01T00:00:00Z',
feed_generated_from: 'api_sync',
total_products: 500,
schema_org: true,
robots_txt: true,
llms_txt: true,
},
interact: {
runtime: 'https://cdn.opencommerceprotocol.org/runtime/v1/ocp-runtime.min.js',
webmcp: true,
tools: ['search_products', 'get_product', 'add_to_cart', 'begin_checkout'],
},
bridge: {
mcp: 'https://mystore.com/mcp',
ucp: 'https://mystore.com/.well-known/ucp',
acp: 'https://mystore.com/acp',
a2a: 'https://mystore.com/.well-known/agent.json',
},
payments: {
handlers: ['card', 'paypal', 'apple_pay'],
currencies: ['USD', 'EUR'],
},
permissions: {
requires_human_checkout: true,
agent_purchase_limit: 500,
rate_limit: '100/hour',
allowed_agent_origins: ['https://chat.openai.com', 'https://claude.ai'],
},
shipping: {
regions: ['US', 'CA', 'GB'],
methods: ['standard', 'express', 'overnight'],
free_above: 50,
},
};OCPProduct
A single product in the JSONL feed.
const product: OCPProduct = {
// Required
id: 'prod-001',
name: 'Premium Wireless Headphones',
price: 149.99,
currency: 'USD',
url: 'https://mystore.com/products/headphones',
// Availability (preferred over deprecated `in_stock`)
availability: 'in_stock', // 'in_stock' | 'out_of_stock' | 'pre_order' | 'backorder' | 'limited' | 'check_site'
availability_updated_at: '2026-03-01T12:00:00Z',
// Product details
description: 'Studio-quality sound with active noise cancellation.',
image: 'https://mystore.com/images/headphones.jpg',
images: ['https://mystore.com/images/headphones-1.jpg'],
category: 'Electronics',
categories: ['Electronics', 'Audio'],
brand: 'SoundMax',
sku: 'SM-WH-001',
tags: ['wireless', 'noise-cancelling', 'bluetooth'],
quantity_available: 42,
original_price: 199.99, // for showing discounts
weight: 0.35,
updated_at: '2026-03-01T00:00:00Z',
// Agent-optimized description — explains product in natural language for AI agents
agent_notes: 'Best-seller. Ideal for frequent flyers and open-plan offices. 30-hour battery. Folds flat for travel. Compatible with all Bluetooth 5.0 devices. Comes with 3.5mm cable for wired use on planes.',
// Variants
variants: [
{ id: 'var-black', name: 'Black', price: 149.99, availability: 'in_stock', sku: 'SM-WH-001-BK' },
{ id: 'var-white', name: 'White', price: 149.99, availability: 'limited', sku: 'SM-WH-001-WH' },
],
// Custom attributes
attributes: { color: 'Black', connectivity: 'Bluetooth 5.0', driver_size: '40mm' },
// B2B fields
specs: [
{ name: 'Driver Size', value: 40, unit: 'mm', group: 'audio' },
{ name: 'Frequency Response', value: '20Hz-20kHz', group: 'audio' },
{ name: 'Weight', value: 350, unit: 'g', group: 'physical' },
],
certifications: [
{ name: 'CE', body: 'European Commission', expires_at: '2027-01-01' },
],
minimum_order_quantity: 1,
lead_time_days: 2,
bulk_pricing: [
{ min_quantity: 10, price: 129.99 },
{ min_quantity: 50, price: 109.99 },
],
// Price intelligence
price_guarantee: { type: 'price_match', details: 'We match any lower price', url: 'https://mystore.com/price-match' },
promotions: [
{ description: '20% off for new customers', discount_type: 'percentage', discount_value: 20, code: 'WELCOME20', valid_until: '2026-12-31' },
],
price_per_unit: { amount: 149.99, unit: 'each' },
};OCPAvailability
type OCPAvailability =
| 'in_stock' // Available to purchase now
| 'out_of_stock' // Currently unavailable
| 'pre_order' // Not yet released, can be ordered
| 'backorder' // Temporarily out of stock, will ship when restocked
| 'limited' // Low stock
| 'check_site'; // Agent should direct user to product pageHandler Types
All 11 OCP tool handler signatures:
import type { OCPHandlers } from '@opencommerceprotocol/spec';
const handlers: Partial<OCPHandlers> = {
search_products: async ({ query, category, min_price, max_price, in_stock, limit, offset, sort }) => {
// Returns: ProductResult[]
},
get_product: async ({ id }) => {
// Returns: OCPProduct
},
get_product_qa: async ({ id, question }) => {
// Returns: QAResult { answer, confidence?, sources? }
},
compare_products: async ({ ids, attributes }) => {
// Returns: ComparisonResult { products, comparison?, spec_matrix?, recommendation? }
},
add_to_cart: async ({ product_id, quantity, variant_id, agent_context }) => {
// Returns: CartResult { success, cart, message? }
},
get_cart: async () => {
// Returns: Cart { items, total, currency, session_id? }
},
update_cart: async ({ items }) => {
// Returns: Cart
},
begin_checkout: async ({ prefill, callback_url, agent_context }) => {
// Returns: CheckoutResult { checkout_url, session_id, expires_at?, ... }
},
check_availability: async ({ id, location, quantity }) => {
// Returns: AvailabilityResult { availability, in_stock, quantity?, ... }
},
check_checkout_status: async ({ session_id }) => {
// Returns: CheckoutStatusResult { session_id, status, order_id?, message?, ... }
},
get_promotions: async ({ product_id, category }) => {
// Returns: PromotionsResult { promotions: Promotion[] }
},
};Agent Context
Agents can pass buyer context when adding to cart or beginning checkout:
import type { AgentContext, BuyerPreferences } from '@opencommerceprotocol/spec';
const agentContext: AgentContext = {
agent_id: 'chatgpt-shopping',
session_ref: 'sess-abc123',
buyer_preferences: {
locale: 'en-US',
shipping_country: 'US',
size: 'M',
color: 'blue',
loyalty_ids: [{ program: 'store-rewards', member_id: 'MBR-001' }],
},
};Checkout Types
import type { BeginCheckoutParams, CheckoutPrefill, CheckoutResult } from '@opencommerceprotocol/spec';
const prefill: CheckoutPrefill = {
email: '[email protected]',
name: 'Jane Doe',
shipping_address: {
line1: '123 Main St',
city: 'Austin',
postal_code: '78701',
country: 'US',
},
payment_method_hint: 'apple_pay',
};Constants
import {
OCP_VERSION, // '1.0'
OCP_MANIFEST_PATH, // '/.well-known/ocp.json'
OCP_FEED_PATH, // '/ocp/products.jsonl'
OCP_DOC_PATH, // '/ocp.md'
OCP_TOOL_DESCRIPTIONS,// Record<string, string> — human-readable descriptions for all 11 tools
OCP_TOOL_NAMES, // string[] — array of all 11 tool names
} from '@opencommerceprotocol/spec';JSON Schemas
import { manifestSchema, productSchema } from '@opencommerceprotocol/spec';
// Use for runtime validation with any JSON Schema validator
import Ajv from 'ajv';
const ajv = new Ajv();
const validate = ajv.compile(manifestSchema);
const valid = validate(myManifest);All 11 Standard Tools
| Tool | Description |
|------|-------------|
| search_products | Search the product catalog |
| get_product | Get detailed product information |
| get_product_qa | Ask questions about a product |
| compare_products | Compare multiple products |
| add_to_cart | Add a product to the cart |
| get_cart | Retrieve current cart contents |
| update_cart | Update cart item quantities |
| begin_checkout | Start a checkout session |
| check_availability | Check product availability |
| check_checkout_status | Poll a checkout session status |
| get_promotions | Get active promotions |
