{
  "openapi": "3.1.1",
  "info": {
    "title": "Lichcards public read API",
    "version": "1.0.0",
    "description": "A description of existing Shopify storefront GET endpoints, verified on Lichcards. No API key is required. Uses locale-aware paths and the caller's presentment-currency session. This is a read-only interface: it grants no customer, order, payment or administration access and provides no cart mutations. Discover native buyer-approved commerce separately through /.well-known/ucp and /agents.md. Product prices alone are not the final checkout total."
  },
  "externalDocs": {
    "description": "Lichcards API guide and agent discovery",
    "url": "https://lichcards.nl/?view=agent-docs"
  },
  "servers": [
    {
      "url": "https://lichcards.nl",
      "description": "Dutch default locale"
    },
    {
      "url": "https://lichcards.nl/en",
      "description": "English locale; does not select the buyer's country"
    },
    {
      "url": "https://lichcards.nl/de",
      "description": "German locale; does not select the buyer's country"
    },
    {
      "url": "https://lichcards.nl/fr",
      "description": "French locale; does not select the buyer's country"
    },
    {
      "url": "https://lichcards.nl/es",
      "description": "Spanish locale; does not select the buyer's country"
    },
    {
      "url": "https://lichcards.nl/it",
      "description": "Italian locale; does not select the buyer's country"
    }
  ],
  "security": [],
  "x-lichcards-access-model": {
    "authentication": "none for these native GET endpoints",
    "oauth_scopes_required": false,
    "permissions": {
      "public_catalog_read": {
        "operations": [
          "getProduct",
          "searchProducts"
        ],
        "data": "Published catalog and product information"
      },
      "visitor_cart_read": {
        "operations": [
          "getSessionCart"
        ],
        "data": "Only the caller's own cart session and currency",
        "context": "Use only the caller's authorized cookies; never share or reuse another visitor's session"
      }
    }
  },
  "tags": [
    {
      "name": "Catalog",
      "description": "Public product data"
    },
    {
      "name": "Session",
      "description": "Only the caller's own session"
    }
  ],
  "paths": {
    "/products/{handle}.js": {
      "get": {
        "operationId": "getProduct",
        "tags": [
          "Catalog"
        ],
        "summary": "Read a product and its variants",
        "description": "Prices are integer Shopify money values in the session's presentment currency. Use a real handle obtained from search or a canonical product URL. A missing product can return an empty 404 body.",
        "security": [],
        "x-lichcards-permission": "public_catalog_read",
        "parameters": [
          {
            "name": "handle",
            "in": "path",
            "required": true,
            "description": "Published product handle.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "151-ultra-premium-collection-deck-box"
          }
        ],
        "responses": {
          "200": {
            "description": "Product JSON. The native endpoint may label JSON as text/javascript.",
            "content": {
              "text/javascript": {
                "schema": {
                  "$ref": "#/components/schemas/Product"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Product"
                }
              }
            }
          },
          "404": {
            "description": "Product not found. The native endpoint may return an empty body; do not assume JSON parsing is possible."
          },
          "429": {
            "description": "Rate limited. Respect Retry-After when present and use backoff.",
            "headers": {
              "Retry-After": {
                "description": "Optional wait interval supplied by the platform.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/search/suggest.json": {
      "get": {
        "operationId": "searchProducts",
        "tags": [
          "Catalog"
        ],
        "summary": "Read a small set of product suggestions",
        "description": "Use the returned handle to read the actual product and selected variant. Search price fields are decimal strings, distinct from the integer .js product money format. This specification supports product-only results.",
        "security": [],
        "x-lichcards-permission": "public_catalog_read",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "pokemon"
          },
          {
            "name": "resources[type]",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "product"
              ]
            },
            "description": "Request product-only results.",
            "required": true,
            "example": "product"
          },
          {
            "name": "resources[limit]",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 10
            },
            "example": 3
          },
          {
            "name": "resources[options][unavailable_products]",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "show",
                "hide",
                "last"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Product suggestions as JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchResults"
                }
              }
            }
          },
          "422": {
            "description": "Invalid search parameters. Correct the parameter named in description before retrying.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchError"
                },
                "example": {
                  "status": 422,
                  "message": "Invalid parameter error",
                  "description": "Type '__ora_invalid' is not supported."
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Respect Retry-After when present and use backoff.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/cart.js": {
      "get": {
        "operationId": "getSessionCart",
        "tags": [
          "Session"
        ],
        "summary": "Read the caller's current cart and currency",
        "description": "Session-specific data belonging to the caller. Without existing cart cookies, a caller starts with its own empty cart. Use currency to interpret .js product money. Do not publish cart tokens, copy another visitor's cookies or assume this is an order API.",
        "security": [],
        "x-lichcards-permission": "visitor_cart_read",
        "x-session-scoped": true,
        "responses": {
          "200": {
            "description": "JSON for only the caller's current session, including ISO presentment currency.",
            "content": {
              "text/javascript": {
                "schema": {
                  "$ref": "#/components/schemas/SessionCart"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionCart"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Respect Retry-After when present and use backoff.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Product": {
        "type": "object",
        "required": [
          "id",
          "title",
          "handle",
          "price",
          "available",
          "variants"
        ],
        "properties": {
          "id": {
            "type": "integer"
          },
          "title": {
            "type": "string"
          },
          "handle": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "vendor": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "price": {
            "type": "integer",
            "minimum": 0,
            "description": "Shopify money in hundredths of the session presentment currency. EUR 2.95 is 295. Read GET /cart.js for the active currency."
          },
          "price_min": {
            "type": "integer",
            "minimum": 0
          },
          "price_max": {
            "type": "integer",
            "minimum": 0
          },
          "available": {
            "type": "boolean",
            "description": "Product-level availability. Inspect the exact selected variant as well."
          },
          "variants": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Variant"
            }
          },
          "images": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "additionalProperties": true
      },
      "Variant": {
        "type": "object",
        "required": [
          "id",
          "title",
          "price",
          "available"
        ],
        "properties": {
          "id": {
            "type": "integer"
          },
          "title": {
            "type": "string"
          },
          "sku": {
            "type": [
              "string",
              "null"
            ]
          },
          "price": {
            "type": "integer",
            "minimum": 0
          },
          "available": {
            "type": "boolean"
          },
          "option1": {
            "type": [
              "string",
              "null"
            ]
          },
          "option2": {
            "type": [
              "string",
              "null"
            ]
          },
          "option3": {
            "type": [
              "string",
              "null"
            ]
          },
          "barcode": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "additionalProperties": true
      },
      "SearchProduct": {
        "type": "object",
        "required": [
          "id",
          "title",
          "handle",
          "url",
          "price",
          "available"
        ],
        "properties": {
          "id": {
            "type": "integer"
          },
          "title": {
            "type": "string"
          },
          "handle": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "price": {
            "type": "string",
            "description": "Decimal price string in the session currency, for example '2.95'. This is not the .js integer money format."
          },
          "available": {
            "type": "boolean"
          },
          "vendor": {
            "type": "string"
          },
          "type": {
            "type": "string"
          }
        },
        "additionalProperties": true
      },
      "SearchResults": {
        "type": "object",
        "required": [
          "resources"
        ],
        "properties": {
          "resources": {
            "type": "object",
            "required": [
              "results"
            ],
            "properties": {
              "results": {
                "type": "object",
                "required": [
                  "products"
                ],
                "properties": {
                  "products": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/SearchProduct"
                    }
                  }
                },
                "additionalProperties": true
              }
            },
            "additionalProperties": true
          }
        },
        "additionalProperties": true
      },
      "SearchError": {
        "type": "object",
        "required": [
          "status",
          "message",
          "description"
        ],
        "properties": {
          "status": {
            "type": [
              "integer",
              "string"
            ],
            "description": "HTTP status represented as a number or numeric string by Shopify."
          },
          "message": {
            "type": "string"
          },
          "description": {
            "type": "string"
          }
        },
        "additionalProperties": true
      },
      "SessionCart": {
        "type": "object",
        "required": [
          "currency",
          "item_count",
          "items",
          "total_price"
        ],
        "properties": {
          "currency": {
            "type": "string",
            "pattern": "^[A-Z]{3}$",
            "description": "ISO 4217 presentment currency for this session."
          },
          "item_count": {
            "type": "integer",
            "minimum": 0
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "total_price": {
            "type": "integer",
            "minimum": 0,
            "description": "Shopify money in hundredths of the session currency."
          }
        },
        "additionalProperties": true
      }
    }
  }
}
