UCP Output

Standardize your procurement and agent pipelines. Native Universal Commerce Protocol (UCP) JSON output.

Design Principle: One schema, any merchant. Every response follows the same structure regardless of the source site. Write one parser, use it everywhere.

What is UCP?

The Universal Commerce Protocol (UCP) defines a strict, unified schema for commerce data. ShopGraph extracts product data across any target URL and normalizes it into UCP line_item format. One schema, regardless of the merchant's architecture. No custom mappers per supplier.

UCP Schema Compatible — Validated against ucp-schema v1.1.0

Using UCP Output

Add format=ucp to any extraction request:

Request
{
  "url": "https://www.allbirds.com/products/mens-tree-runners",
  "format": "ucp"
}

UCP Line Item Output

Interface

UcpLineItem
interface UcpLineItem {
  id: string;                    // Stable identifier (shopgraph::domain::slug)
  name: string;                  // Product name
  description: string | null;    // Product description
  unit_price: {
    amount: number;              // Price in smallest currency unit (cents)
    currency: string;            // ISO 4217 currency code
  } | null;
  quantity: number;              // Always 1 for single product extraction
  sku: string | null;            // Product SKU
  brand: string | null;          // Brand name
  category: string | null;       // Product category
  image_url: string | null;      // Primary image URL
  product_url: string;           // Canonical product URL
  availability: string | null;   // in_stock, out_of_stock, pre_order
  _extensions: {
    shopgraph: {
      extraction_method: string;
      confidence_score: number;
      field_confidence: Record;
    };
    b2b?: {                      // Present for B2B products
      moq: number | null;
      lead_time: string | null;
      bulk_pricing: BulkTier[];
      manufacturer_part_number: string | null;
    };
  };
}

Response

UCP Response
{
  "line_item": {
    "id": "shopgraph::allbirds::mens-tree-runners",
    "name": "Men's Tree Runners",
    "description": "Lightweight, breathable sneakers...",
    "unit_price": {
      "amount": 9800,
      "currency": "USD"
    },
    "quantity": 1,
    "sku": "TR-M-001",
    "brand": "Allbirds",
    "category": "Footwear > Sneakers",
    "image_url": "https://cdn.allbirds.com/image/fetch/...",
    "product_url": "https://www.allbirds.com/products/mens-tree-runners",
    "availability": "in_stock",
    "_extensions": {
      "shopgraph": {
        "extraction_method": "schema_org",
        "confidence_score": 0.93,
        "access_routing": {
          "cdn_gate_detected": "cloudflare_turnstile",
          "auth_method": "rfc_9421_signature",
          "access_readiness_score": 0
        },
        "field_confidence": {
          "name": 0.98,
          "unit_price": 0.97,
          "brand": 0.94,
          "availability": 0.91
        }
      }
    }
  },
  "_extraction_status": "complete"
}

Note: The access_routing block appears in responses when the access_readiness dimension is active. This dimension is currently at weight 0.00 and activates when Web Bot Auth adoption reaches detection threshold. All other fields are live today.

Key Differences from Standard Output

Standard FieldUCP FieldNotes
product.titleline_item.nameDirect mapping
product.priceline_item.unit_price.amountConverted to cents (integer)
product.currencyline_item.unit_price.currencyISO 4217
_shopgraph.*_extensions.shopgraph.*Metadata in UCP extensions
_shopgraph.access_routing_extensions.shopgraph.access_routingAccess routing metadata

Field Mapping

Every field from the standard ProductData response maps to a UcpLineItem field:

ProductDataUcpLineItemTransformation
titlenameDirect
priceunit_price.amountMultiplied by 100 (dollars to cents)
currencyunit_price.currencyDirect
descriptiondescriptionDirect
skuskuDirect
brandbrandDirect
categorycategoryDirect
imageimage_urlDirect
urlproduct_urlDirect
availabilityavailabilityNormalized to lowercase with underscores
moq_extensions.b2b.moqMoved to B2B extension
lead_time_extensions.b2b.lead_timeMoved to B2B extension
bulk_pricing_extensions.b2b.bulk_pricingMoved to B2B extension
mpn_extensions.b2b.manufacturer_part_numberMoved to B2B extension

B2B Extensions

When B2B fields are detected (MOQ, lead time, bulk pricing, MPN), they are placed in the _extensions.b2b namespace:

B2B extensions example
{
  "_extensions": {
    "shopgraph": {
      "extraction_method": "hybrid",
      "confidence_score": 0.85
    },
    "b2b": {
      "moq": 10,
      "lead_time": "3-5 business days",
      "bulk_pricing": [
        { "min_quantity": 10, "price": 135.00 },
        { "min_quantity": 50, "price": 128.50 },
        { "min_quantity": 100, "price": 122.00 }
      ],
      "manufacturer_part_number": "4M206"
    }
  }
}

Extraction Status

When extraction is partial, the _extraction_status field indicates quality:

StatusMeaning
completeAll core fields extracted successfully
partialSome fields missing or below confidence threshold
minimalOnly name and URL available
failedExtraction failed entirely

Note: If you apply a strict_confidence_threshold to a request, fields falling below that threshold are omitted from the line_item, and the _extraction_status will downgrade to partial. For agent routing workflows, we recommend omitting the threshold and evaluating the field_confidence block directly.

Example: Catalog Ingestion

A nightly pipeline processes supplier URLs across Shopify, Uline, and McMaster-Carr. Each response comes back as a UCP line_item. The pipeline writes one parser regardless of the merchant's native data format.

JavaScript
const result = await fetch('https://shopgraph.dev/api/enrich', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer sg_live_your_key'
  },
  body: JSON.stringify({
    url: supplierUrl,
    format: 'ucp',
    strict_confidence_threshold: 0.85
  })
});

const data = await result.json();
await catalog.upsert(data.line_item);  // Same shape for every merchant

UCP output combined with threshold filtering. One integration path for any supplier URL.

What this unlocks: One integration for every merchant. Your pipeline consumes UCP line_items regardless of whether the source is Shopify, Uline, or McMaster-Carr. No per-supplier mappers. No custom parsers.