Status: Draft
Version: 2025-10-06
Scope: Product details and merchant offers
This RFC defines the Product Listing API, a standardized REST API contract that product data providers SHOULD implement to expose detailed product information and merchant offers to AI agents.
The product data provider remains the system of record for all product details, pricing, inventory, and merchant relationships.
This specification ensures that:
- Product details are authoritative from the source provider.
- Merchant offers include pricing, availability, shipping, and payment options.
- AI agents can retrieve comprehensive product data for comparison and purchase decisions.
- Provide a stable, versioned API surface (
API-Version: 2025-10-06) that AI agents call to retrieve product listings. - Expose detailed product information including specifications, ratings, images, and categories.
- Provide comprehensive merchant offers with pricing, shipping, stock status, and payment methods.
- Support multiple lookup methods: by product ID, GTIN/UPC/EAN, or merchant URL.
- Enable price filtering for merchant offers.
Out of scope: Order placement, inventory management, merchant onboarding, review moderation, return policies.
The key words MUST, MUST NOT, SHOULD, MAY follow RFC 2119/8174.
- Versioning: Client (AI agent) MUST send
API-Version. Server MUST validate support (e.g.,2025-10-06). - Authentication: Server MUST require
Authorization: Bearer <token>for all requests. - Rate Limiting: Server SHOULD implement rate limiting and return appropriate
429responses.
- By Product ID —
GET /products/{id}retrieves a single product listing. - By GTIN —
GET /products/by-gtin/{gtin}retrieves product by GTIN/UPC/EAN. - By URL —
POST /products/by-urlretrieves product by merchant offer URL. - Batch Retrieval —
GET /productsretrieves multiple products by IDs or GTINs.
All endpoints MUST use HTTPS and return JSON. Prices SHOULD be represented as strings with decimal notation.
Request Headers (sent by AI agent):
Authorization: Bearer <token>(REQUIRED)Content-Type: application/json(REQUIRED for POST requests)Accept-Language: <locale>(e.g.,en-US) (RECOMMENDED)User-Agent: <string>(RECOMMENDED)Request-Id: <string>(RECOMMENDED)API-Version: 2025-10-06(REQUIRED)
Response Headers:
Request-Id— echo if providedCache-Control— caching directives (RECOMMENDED)
Error Shape (flat):
{
"type": "not_found",
"code": "product_not_found",
"message": "No product found with the given identifier",
"param": "id"
}Where type ∈ invalid_request | not_found | rate_limit_exceeded | service_unavailable. param is optional.
GET /products/{productId} → 200 OK
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
productId |
string | Yes | Unique product identifier |
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
countryCode |
string | Yes | ISO 3166-1 alpha-2 country code |
minPrice |
number | No | Minimum offer price (filters offers) |
maxPrice |
number | No | Maximum offer price (filters offers) |
itemCondition |
string | No | Comma-separated: new, refurbished, used (default: new) |
includeOutOfStock |
boolean | No | Include out-of-stock offers (default: false) |
Response Body:
{
"product": {
"id": "prod_12345",
"name": "Premium Wireless Headphones",
"description": "High-quality wireless headphones with active noise cancellation...",
"brand": {
"id": "brand_123",
"name": "AudioTech",
"logoUrl": "https://images.example.com/brands/brand_123.png"
},
"category": {
"id": "cat_456",
"name": "Electronics > Audio > Headphones",
"breadcrumbs": ["Electronics", "Audio", "Headphones"]
},
"images": [
{
"url": "https://images.example.com/prod_12345_main.jpg",
"type": "main",
"width": 1200,
"height": 1200
}
],
"identifiers": {
"gtin": "00012345678905",
"mpn": "WH-1000XM5",
"sku": "ATH-WH1000"
},
"specifications": {
"color": "Black",
"connectivity": "Bluetooth 5.2",
"battery_life": "30 hours",
"weight": "250g"
},
"rating": {
"average": "4.5",
"count": 1234,
"distribution": {
"5": 800,
"4": 300,
"3": 100,
"2": 24,
"1": 10
}
},
"popularity": {
"rank": 1,
"categoryRank": 1,
"globalRank": 145
},
"url": "https://example.com/products/prod_12345"
},
"offers": [
{
"id": "offer_789",
"merchant": {
"id": "merchant_456",
"name": "TechStore",
"logoUrl": "https://images.example.com/merchants/merchant_456.png",
"verified": true
},
"name": "Premium Wireless Headphones - Black Edition",
"url": "https://techstore.com/products/headphones-wh1000",
"price": {
"value": "199.99",
"currency": "USD"
},
"shippingCost": {
"value": "5.99",
"currency": "USD",
"freeShippingThreshold": {
"value": "50.00",
"currency": "USD"
}
},
"availability": {
"status": "in_stock",
"quantity": 15,
"restockDate": null
},
"delivery": {
"minDays": 2,
"maxDays": 5,
"estimatedDate": "2025-10-11"
},
"condition": "new",
"returnable": true,
"returnWindow": 30,
"warranty": {
"duration": 12,
"type": "manufacturer"
},
"paymentMethods": [
{
"type": "credit_card",
"brands": ["visa", "mastercard", "amex"]
},
{
"type": "digital_wallet",
"providers": ["apple_pay", "google_pay", "paypal"]
}
],
"identifiers": {
"sku": "TECH-WH1000-BLK",
"gtin": "00012345678905"
}
}
],
"priceRange": {
"min": {
"value": "199.99",
"currency": "USD"
},
"max": {
"value": "249.99",
"currency": "USD"
}
},
"metadata": {
"lastUpdated": "2025-10-06T14:30:00Z",
"offerCount": 12,
"inStockOfferCount": 8
}
}GET /products/by-gtin/{gtin} → 200 OK
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
gtin |
string | Yes | GTIN-8, GTIN-12, GTIN-13, or GTIN-14 |
Query Parameters: Same as Get Product Listing by ID.
Response: Same structure as Get Product Listing by ID.
POST /products/by-url → 200 OK
Request Body:
{
"url": "https://merchant.com/products/item-12345",
"countryCode": "US"
}Response: Same structure as Get Product Listing by ID.
GET /products → 200 OK
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
ids |
string | No* | Comma-separated product IDs (max 20) |
gtins |
string | No* | Comma-separated GTINs (max 20) |
countryCode |
string | Yes | ISO 3166-1 alpha-2 country code |
*One of ids or gtins MUST be provided.
Response Body:
{
"products": [
{
"product": {
/* Product object */
},
"offers": [
/* Array of offers */
],
"priceRange": {
/* Price range */
},
"metadata": {
/* Metadata */
}
}
]
}| Field | Type | Required | Description |
|---|---|---|---|
id |
string | Yes | Unique product identifier |
name |
string | Yes | Product name |
description |
string | No | Full product description |
brand |
Brand | No | Product brand |
category |
Category | No | Product category |
images |
Image[] | Yes | Product images |
identifiers |
Identifiers | No | Product identifiers |
specifications |
object | No | Key-value specifications |
rating |
Rating | No | Product ratings |
popularity |
Popularity | No | Popularity metrics |
url |
string (URI) | Yes | Product page URL |
| Field | Type | Required | Description |
|---|---|---|---|
id |
string | Yes | Unique offer identifier |
merchant |
Merchant | Yes | Merchant information |
name |
string | Yes | Offer name |
url |
string (URI) | Yes | Direct link to merchant offer |
price |
Price | Yes | Offer price |
shippingCost |
ShippingCost | No | Shipping cost details |
availability |
Availability | Yes | Stock availability |
delivery |
Delivery | No | Delivery information |
condition |
string | Yes | new, refurbished, used |
returnable |
boolean | No | Whether returns are accepted |
returnWindow |
integer | No | Return window in days |
warranty |
Warranty | No | Warranty information |
paymentMethods |
PaymentMethod[] | No | Accepted payment methods |
identifiers |
Identifiers | No | Merchant-specific identifiers |
Brand:
{
"id": "string",
"name": "string",
"logoUrl": "string (URI, optional)"
}Category:
{
"id": "string",
"name": "string",
"breadcrumbs": ["string"] // optional
}Image:
{
"url": "string (URI)",
"type": "main | alternate | lifestyle", // optional
"width": "integer", // optional
"height": "integer" // optional
}Identifiers:
{
"gtin": "string", // optional
"mpn": "string", // optional (manufacturer part number)
"sku": "string" // optional
}Price:
{
"value": "string (decimal)",
"currency": "string (ISO 4217)"
}ShippingCost:
{
"value": "string (decimal)",
"currency": "string (ISO 4217)",
"freeShippingThreshold": {
// optional
"value": "string (decimal)",
"currency": "string (ISO 4217)"
}
}Availability:
{
"status": "in_stock | out_of_stock | preorder | limited | unknown",
"quantity": "integer", // optional
"restockDate": "string (ISO 8601)" // optional
}Delivery:
{
"minDays": "integer",
"maxDays": "integer",
"estimatedDate": "string (ISO 8601)" // optional
}Merchant:
{
"id": "string",
"name": "string",
"logoUrl": "string (URI)", // optional
"verified": "boolean" // optional
}Rating:
{
"average": "string (decimal)",
"count": "integer",
"distribution": {
// optional
"5": "integer",
"4": "integer",
"3": "integer",
"2": "integer",
"1": "integer"
}
}Popularity:
{
"rank": "integer", // optional (category rank)
"categoryRank": "integer", // optional
"globalRank": "integer" // optional
}Warranty:
{
"duration": "integer (months)",
"type": "manufacturer | extended | store"
}PaymentMethod:
{
"type": "credit_card | debit_card | digital_wallet | bank_transfer | buy_now_pay_later",
"brands": ["string"], // e.g., ["visa", "mastercard"] - optional
"providers": ["string"] // e.g., ["paypal", "apple_pay"] - optional
}productIdMUST be a valid identifier.gtinMUST be 8, 12, 13, or 14 digits.countryCodeMUST be ISO 3166-1 alpha-2.minPriceandmaxPriceMUST be positive numbers.itemConditionMUST be one of:new,refurbished,used.- Batch requests MUST not exceed 20 items.
currencyMUST be ISO 4217 (uppercase recommended).
- Authentication:
Authorization: Bearer <token>REQUIRED. - Rate Limiting: Implement appropriate limits to prevent abuse.
- Input Validation: Sanitize all parameters to prevent injection attacks.
- TLS: All requests MUST use HTTPS/TLS 1.2+.
- Data Privacy: Comply with applicable data protection regulations.
- Merchant Data: Ensure merchant data is accurate and up-to-date.
- Product data SHOULD be cacheable for 5-15 minutes.
- Offer data SHOULD be cacheable for 1-5 minutes (pricing changes frequently).
- Use
Cache-Controlheaders appropriately. - Include
ETagorLast-Modifiedheaders when possible.
| Code | Meaning | When to Use |
|---|---|---|
| 200 | OK | Request succeeded |
| 400 | Bad Request | Invalid parameters |
| 401 | Unauthorized | Missing or invalid authentication |
| 404 | Not Found | Product not found |
| 429 | Too Many Requests | Rate limit exceeded |
| 503 | Service Unavailable | Temporary service unavailability |
{
"type": "not_found",
"code": "product_not_found",
"message": "No product found with ID: prod_12345",
"param": "productId"
}GET /products/prod_12345?countryCode=US&minPrice=100&maxPrice=300 HTTP/1.1
Host: api.example.com
Authorization: Bearer token_abc123
API-Version: 2025-10-06
Accept-Language: en-USGET /products/by-gtin/00012345678905?countryCode=US HTTP/1.1
Host: api.example.com
Authorization: Bearer token_abc123
API-Version: 2025-10-06POST /products/by-url HTTP/1.1
Host: api.example.com
Authorization: Bearer token_abc123
API-Version: 2025-10-06
Content-Type: application/json
{
"url": "https://merchant.com/products/wireless-headphones-12345",
"countryCode": "US"
}- Enforces HTTPS and JSON
- Requires
API-Version: 2025-10-06 - Requires
Authorization: Bearer <token> - Implements
/products/{id}endpoint - Supports product lookup by GTIN
- Supports product lookup by URL
- Supports batch product retrieval
- Returns comprehensive product details
- Returns merchant offers with pricing and availability
- Implements offer filtering by price and condition
- Returns flat error objects with type/code/message
- Implements rate limiting
- Uses appropriate cache headers
- 2025-10-06: Initial draft; defined product listing endpoints with multiple lookup methods and comprehensive offer details.