{
  "openapi": "3.1.0",
  "info": {
    "title": "JENNi Shop Local API",
    "description": "Autonomous commerce API for AI agents and ChatGPT Custom GPT Actions on shop.jennipro.com.\nProduct-first: search products for any 5-digit US ZIP code, read one product with its size/colour variants, and start a buyer-approved guest checkout.\nEach product carries JENNi's single best offer: price, delivery_promise (local delivery: \"Get it today\" only when the cutoff allows, otherwise \"We'll deliver by <Month D>\"; \"Ships to you\" for ship-to-home) and fulfilled_by \"Delivered by JENNi\".\nJENNi picks the store that fulfils the order; the agent never needs to choose one.\nComplete discovery uses explicit mode=canonical_discovery on public REST when enabled. No-mode public REST always retains the legacy offer projection. Canonical membership does not imply directory coverage, offers or checkout; completion is unavailable.",
    "version": "1.0.0",
    "contact": {
      "name": "JENNi Support",
      "email": "support@jennipro.com",
      "url": "https://shop.jennipro.com/contact"
    }
  },
  "servers": [
    {
      "url": "https://shop.jennipro.com",
      "description": "Production Storefront API"
    }
  ],
  "paths": {
    "/api/v1/search": {
      "get": {
        "operationId": "searchCatalog",
        "summary": "Complete canonical discovery",
        "parameters": [
          {
            "name": "query",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 256,
              "description": "Optional title, brand, UPC or GTIN keyword. Omit to enumerate approved root catalog facts."
            }
          },
          {
            "name": "product_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 128
            }
          },
          {
            "name": "gtin",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{8,14}$"
            }
          },
          {
            "name": "brand",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 256
            }
          },
          {
            "name": "store_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Unsupported for catalog facts; nonempty store filters are rejected."
            }
          },
          {
            "name": "store_ids",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "maxItems": 0,
              "items": {
                "type": "string"
              },
              "description": "Empty normalizes to absent; store filtering is unsupported."
            }
          },
          {
            "name": "zip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{5}(?:-[0-9]{4})?$",
              "description": "Optional echoed caller context only; never filters facts."
            }
          },
          {
            "name": "postal_code",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{5}(?:-[0-9]{4})?$",
              "description": "Optional echoed caller context only; never filters facts."
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 8192,
              "description": "Confidential opaque upstream continuation; forward unchanged with the same selectors and limit."
            }
          }
        ],
        "responses": {
          "200": {
            "headers": {
              "cache-control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "x-jenni-catalog-authority": {
                "schema": {
                  "type": "string",
                  "const": "jenni_catalog_facts"
                }
              },
              "x-jenni-catalog-policy-version": {
                "schema": {
                  "type": "string",
                  "const": "2026-10-16.v1"
                }
              },
              "x-jenni-catalog-policy-hash": {
                "schema": {
                  "type": "string",
                  "const": "1340ae7f5b87d590b5107d90c6ace904a0b38419101e211f39f5bbaa84e704a1"
                }
              }
            },
            "description": "Exact PAS canonical envelope. Approved nullable facts only; images/offers empty, stock unknown. Checkout is never authorized by discovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalDiscovery"
                }
              }
            }
          },
          "400": {
            "description": "Unsupported filters or refused confidential cursor; never restarted automatically."
          },
          "404": {
            "description": "Canonical resource absent (product only); search errors remain errors."
          },
          "503": {
            "description": "Discovery disabled, unavailable or publication/permission proof invalid."
          }
        }
      }
    },
    "/api/v1/stores": {
      "get": {
        "operationId": "findStores",
        "summary": "Find a shop by name (optional, not part of the buying flow)",
        "description": "Optional. Use only when the shopper names a specific shop. Not needed to buy anything: searchCatalog, getProduct and startCheckout cover the default flow and JENNi picks the store. Read-only. Returns each shop's store_id, name, address, and storefront URL.",
        "parameters": [
          {
            "name": "name",
            "in": "query",
            "required": true,
            "description": "Shop name or search phrase (e.g. 'Cheeky Monkey')",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "zip",
            "in": "query",
            "required": false,
            "description": "5-digit US ZIP code to sort by nearest shops",
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{5}$"
            }
          },
          {
            "name": "market",
            "in": "query",
            "required": false,
            "description": "Market key (e.g. 'san-antonio-tx')",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Number of shops to return (1-20, default 10)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 20,
              "default": 10
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Matching local shops",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "name",
                    "stores",
                    "partial"
                  ],
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "location": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "partial": {
                      "type": "boolean"
                    },
                    "next_step": {
                      "type": "string"
                    },
                    "stores": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "store_id",
                          "name",
                          "address",
                          "distance_miles",
                          "url"
                        ],
                        "properties": {
                          "store_id": {
                            "type": "string"
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "address": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "distance_miles": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "url": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid parameters"
          }
        }
      }
    },
    "/api/v1/products/{productId}": {
      "get": {
        "operationId": "getProduct",
        "summary": "Canonical product discovery",
        "parameters": [
          {
            "name": "productId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "postal_code",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{5}(?:-[0-9]{4})?$",
              "description": "Optional echoed caller context only; never filters facts."
            }
          },
          {
            "name": "zip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{5}(?:-[0-9]{4})?$",
              "description": "Optional echoed caller context only; never filters facts."
            }
          }
        ],
        "responses": {
          "200": {
            "headers": {
              "cache-control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "x-jenni-catalog-authority": {
                "schema": {
                  "type": "string",
                  "const": "jenni_catalog_facts"
                }
              },
              "x-jenni-catalog-policy-version": {
                "schema": {
                  "type": "string",
                  "const": "2026-10-16.v1"
                }
              },
              "x-jenni-catalog-policy-hash": {
                "schema": {
                  "type": "string",
                  "const": "1340ae7f5b87d590b5107d90c6ace904a0b38419101e211f39f5bbaa84e704a1"
                }
              }
            },
            "description": "Exact PAS canonical envelope. Approved nullable facts only; images/offers empty, stock unknown. Checkout is never authorized by discovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalDiscovery"
                }
              }
            }
          },
          "400": {
            "description": "Unsupported filters or refused confidential cursor; never restarted automatically."
          },
          "404": {
            "description": "Canonical resource absent (product only); search errors remain errors."
          },
          "503": {
            "description": "Discovery disabled, unavailable or publication/permission proof invalid."
          }
        }
      }
    },
    "/api/v1/checkout/start": {
      "post": {
        "operationId": "startCheckout",
        "summary": "Start buyer checkout for JENNi's best offer",
        "description": "Send product_id (the exact variant), zip and quantity; store_id is optional because JENNi picks the store. Re-checks stock, price and delivery for the requested quantity and destination ZIP. Returns a secure, hosted storefront checkout URL. The buyer approves the order and completes payment directly on JENNi's hosted checkout page. The agent never collects or handles raw payment card data.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "product_id",
                  "zip",
                  "quantity",
                  "fulfillment_mode"
                ],
                "properties": {
                  "product_id": {
                    "type": "string",
                    "description": "The exact item: variant's product_id when it has sizes or colours"
                  },
                  "store_id": {
                    "type": "string",
                    "description": "Optional. Omit it and JENNi picks the best eligible store; pass one only to keep a specific offer's store."
                  },
                  "quantity": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 10000,
                    "default": 1,
                    "description": "Number of units to purchase"
                  },
                  "zip": {
                    "type": "string",
                    "pattern": "^[0-9]{5}$",
                    "description": "5-digit US delivery ZIP code (e.g. 78205)"
                  },
                  "fulfillment_mode": {
                    "type": "string",
                    "enum": [
                      "local_delivery",
                      "ship_to_home"
                    ],
                    "description": "Keep the fulfillment mode chosen from get_buying_options; required with quantity when canonical discovery is enabled."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Secure checkout redirect URL generated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "kind",
                    "checkout_url",
                    "next_step"
                  ],
                  "properties": {
                    "kind": {
                      "type": "string",
                      "enum": [
                        "basket"
                      ],
                      "description": "Opens a JENNi page at checkout_url where the shopper orders; give the shopper that URL."
                    },
                    "checkout_url": {
                      "type": "string",
                      "description": "Direct storefront URL where buyer pays as guest"
                    },
                    "item": {
                      "type": "string"
                    },
                    "unit_price": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "quantity": {
                      "type": "integer"
                    },
                    "next_step": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Offer is not eligible for checkout or validation error"
          }
        }
      }
    },
    "/public/v1/search": {
      "get": {
        "operationId": "publicCanonicalSearch",
        "description": "Explicit canonical mode recommended for complete discovery. Without mode this route retains its legacy offer projection at every flag state. Destination is echoed context only; store filters are rejected.",
        "parameters": [
          {
            "name": "mode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "const": "canonical_discovery"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 256,
              "description": "Optional title, brand, UPC or GTIN keyword. Omit to enumerate approved root catalog facts."
            }
          },
          {
            "name": "product_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 128
            }
          },
          {
            "name": "gtin",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{8,14}$"
            }
          },
          {
            "name": "brand",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 256
            }
          },
          {
            "name": "store_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Unsupported for catalog facts; nonempty store filters are rejected."
            }
          },
          {
            "name": "store_ids",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "maxItems": 0,
              "items": {
                "type": "string"
              },
              "description": "Empty normalizes to absent; store filtering is unsupported."
            }
          },
          {
            "name": "postal_code",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{5}(?:-[0-9]{4})?$",
              "description": "Optional echoed caller context only; never filters facts."
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 8192,
              "description": "Confidential opaque upstream continuation; forward unchanged with the same selectors and limit."
            }
          }
        ],
        "responses": {
          "200": {
            "headers": {
              "cache-control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "x-jenni-catalog-authority": {
                "schema": {
                  "type": "string",
                  "const": "jenni_catalog_facts"
                }
              },
              "x-jenni-catalog-policy-version": {
                "schema": {
                  "type": "string",
                  "const": "2026-10-16.v1"
                }
              },
              "x-jenni-catalog-policy-hash": {
                "schema": {
                  "type": "string",
                  "const": "1340ae7f5b87d590b5107d90c6ace904a0b38419101e211f39f5bbaa84e704a1"
                }
              }
            },
            "description": "Exact PAS canonical envelope. Approved nullable facts only; images/offers empty, stock unknown. Checkout is never authorized by discovery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalDiscovery"
                }
              }
            }
          },
          "400": {
            "description": "Unsupported filters or refused confidential cursor; never restarted automatically."
          },
          "404": {
            "description": "Canonical resource absent (product only); search errors remain errors."
          },
          "503": {
            "description": "Discovery disabled, unavailable or publication/permission proof invalid."
          }
        }
      }
    },
    "/public/v1/products/{productId}": {
      "get": {
        "operationId": "publicCanonicalProduct",
        "description": "With mode=canonical_discovery, returns approved facts with no offers; postal_code is context only. Omit mode to read owner buying options: pass the buyer's exact postal_code, quantity and fulfillment_mode. The owner response has id/offers and per-offer productId/storeId/price context; only an exact eligible offer can continue to buyer-approved hosted checkout. This read never purchases or charges.",
        "parameters": [
          {
            "name": "productId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "mode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "const": "canonical_discovery"
            }
          },
          {
            "name": "postal_code",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{5}(?:-[0-9]{4})?$",
              "description": "Optional echoed caller context only; never filters facts."
            }
          },
          {
            "name": "quantity",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 10000,
              "description": "Owner buying-options read only; omit mode."
            }
          },
          {
            "name": "fulfillment_mode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "local_delivery",
                "ship_to_home"
              ],
              "description": "Owner buying-options read only; omit mode."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Canonical envelope when mode is explicit; owner product/offers when mode is omitted. Shapes have distinct required keys.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/CanonicalDiscovery"
                    },
                    {
                      "type": "object",
                      "required": [
                        "id",
                        "offers"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "Owner product/family identity; each offer names its exact productId."
                        },
                        "title": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "offers": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "required": [
                              "productId",
                              "storeId",
                              "priceCents",
                              "orderPath"
                            ],
                            "properties": {
                              "productId": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "storeId": {
                                "type": "string"
                              },
                              "priceCents": {
                                "type": [
                                  "integer",
                                  "null"
                                ]
                              },
                              "fulfillmentMode": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "enum": [
                                  "local_delivery",
                                  "ship_to_home",
                                  null
                                ]
                              },
                              "orderPath": {
                                "type": "string",
                                "enum": [
                                  "deliver",
                                  "arranged",
                                  "discovery"
                                ]
                              },
                              "pricing": {
                                "type": [
                                  "object",
                                  "null"
                                ],
                                "description": "Owner price with complete, expires_at and exact postal_code/quantity/fulfillment_mode context. An unknown or mismatched price never authorizes checkout."
                              }
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Unsupported filters or refused confidential cursor; never restarted automatically."
          },
          "404": {
            "description": "Canonical resource absent (product only); search errors remain errors."
          },
          "503": {
            "description": "Discovery disabled, unavailable or publication/permission proof invalid."
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "CanonicalDiscovery": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "mode",
          "contract_version",
          "items",
          "next_cursor",
          "exhausted",
          "catalog_authority",
          "offer_policy",
          "requested_context",
          "source_observed_at",
          "snapshot_semantics"
        ],
        "properties": {
          "mode": {
            "type": "string",
            "const": "canonical_discovery"
          },
          "contract_version": {
            "type": "string",
            "const": "catalog_facts_v1"
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "id",
                "title",
                "brand",
                "upc",
                "gtin",
                "category",
                "images",
                "offers",
                "stock_state",
                "checkout_eligible"
              ],
              "properties": {
                "id": {
                  "type": "string",
                  "pattern": "^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$"
                },
                "title": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "brand": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "upc": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "gtin": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "category": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "id",
                    "name"
                  ],
                  "properties": {
                    "id": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "name": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                },
                "images": {
                  "type": "array",
                  "maxItems": 0,
                  "items": {
                    "type": "string"
                  }
                },
                "offers": {
                  "type": "array",
                  "maxItems": 0,
                  "items": {
                    "type": "string"
                  }
                },
                "stock_state": {
                  "type": "string",
                  "const": "unknown"
                },
                "checkout_eligible": {
                  "type": "boolean",
                  "const": false
                }
              }
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          },
          "exhausted": {
            "type": "boolean"
          },
          "catalog_authority": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "kind",
              "version",
              "policy_hash"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "const": "jenni_catalog_facts"
              },
              "version": {
                "type": "string",
                "const": "2026-10-16.v1"
              },
              "policy_hash": {
                "type": "string",
                "const": "1340ae7f5b87d590b5107d90c6ace904a0b38419101e211f39f5bbaa84e704a1"
              }
            }
          },
          "offer_policy": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "state"
            ],
            "properties": {
              "state": {
                "type": "string",
                "const": "not_requested"
              }
            }
          },
          "requested_context": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "postal_code"
            ],
            "properties": {
              "postal_code": {
                "type": [
                  "string",
                  "null"
                ],
                "pattern": "^[0-9]{5}(?:-[0-9]{4})?$"
              }
            }
          },
          "source_observed_at": {
            "type": "string",
            "format": "date-time"
          },
          "snapshot_semantics": {
            "type": "string",
            "const": "live_keyset"
          }
        }
      },
      "CanonicalSearch": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "query": {
            "type": "string",
            "maxLength": 256,
            "description": "Optional title, brand, UPC or GTIN keyword. Omit to enumerate approved root catalog facts."
          },
          "product_id": {
            "type": "string",
            "maxLength": 128
          },
          "gtin": {
            "type": "string",
            "pattern": "^[0-9]{8,14}$"
          },
          "brand": {
            "type": "string",
            "maxLength": 256
          },
          "store_id": {
            "type": "string",
            "description": "Unsupported for catalog facts; nonempty store filters are rejected."
          },
          "store_ids": {
            "type": "array",
            "maxItems": 0,
            "items": {
              "type": "string"
            },
            "description": "Empty normalizes to absent; store filtering is unsupported."
          },
          "zip": {
            "type": "string",
            "pattern": "^[0-9]{5}(?:-[0-9]{4})?$",
            "description": "Optional echoed caller context only; never filters facts."
          },
          "postal_code": {
            "type": "string",
            "pattern": "^[0-9]{5}(?:-[0-9]{4})?$",
            "description": "Optional echoed caller context only; never filters facts."
          },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100,
            "default": 20
          },
          "cursor": {
            "type": "string",
            "maxLength": 8192,
            "description": "Confidential opaque upstream continuation; forward unchanged with the same selectors and limit."
          }
        }
      }
    }
  }
}