{
  "openapi": "3.1.0",
  "info": {
    "title": "stood.it API",
    "description": "API for browsing and purchasing sustainable wooden laptop stands from stood.it. European micro brand since 2015, FSC-certified beech wood. Ships worldwide from Italy.",
    "version": "1.0.0",
    "contact": {
      "name": "stood",
      "url": "https://stood.it",
      "email": "info@stood.it"
    }
  },
  "servers": [
    {
      "url": "https://stood.it",
      "description": "Production"
    }
  ],
  "paths": {
    "/api/catalog/index.json": {
      "get": {
        "operationId": "getCatalogIndex",
        "summary": "List available catalog locales",
        "description": "Returns all supported locales with links to their catalog JSON files. Start here to discover available languages.",
        "responses": {
          "200": {
            "description": "Locale index",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CatalogIndex"
                }
              }
            }
          }
        }
      }
    },
    "/api/catalog/{locale}.json": {
      "get": {
        "operationId": "getCatalog",
        "summary": "Get product catalog for a locale",
        "description": "Returns all products with prices, variants, images, availability, shipping info, and descriptions in the requested locale. Pre-rendered at build time. Includes buy endpoint instructions.",
        "parameters": [
          {
            "name": "locale",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": ["en", "de", "fr", "it", "es", "nl", "ja", "zh", "ko", "sv"]
            },
            "description": "Language/locale code"
          }
        ],
        "responses": {
          "200": {
            "description": "Product catalog",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Catalog"
                }
              }
            }
          }
        }
      }
    },
    "/api/buy": {
      "get": {
        "operationId": "buyProductLink",
        "summary": "Clickable buy link — redirects to checkout",
        "description": "Validates product and address, then redirects (302) to checkout with cart and address pre-filled. Use for clickable buy links. Rate-limited to 10 req/min/IP.",
        "parameters": [
          { "name": "items", "in": "query", "schema": { "type": "string" }, "description": "Comma-separated items: productId:variantId:quantity (e.g. laptop-stand:slim:1,eco-tablet-stand::2). Use this for multi-item orders. Alternative to productId param.", "example": "laptop-stand:slim:1,eco-tablet-stand::2" },
          { "name": "productId", "in": "query", "schema": { "type": "string" }, "description": "Product ID (single-item shorthand, alternative to items param)", "example": "laptop-stand" },
          { "name": "variantId", "in": "query", "schema": { "type": "string" }, "description": "Variant ID for single-item shorthand", "example": "slim" },
          { "name": "quantity", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 10, "default": 1 }, "description": "Quantity for single-item shorthand" },
          { "name": "locale", "in": "query", "schema": { "type": "string", "enum": ["en", "de", "fr", "it", "es", "nl", "ja", "zh", "ko", "sv"], "default": "en" }, "description": "Checkout locale" },
          { "name": "line1", "in": "query", "required": true, "schema": { "type": "string" }, "description": "Shipping street address", "example": "Hauptstraße 42" },
          { "name": "line2", "in": "query", "schema": { "type": "string" }, "description": "Shipping address line 2" },
          { "name": "postalCode", "in": "query", "required": true, "schema": { "type": "string" }, "description": "Shipping postal code", "example": "10115" },
          { "name": "city", "in": "query", "required": true, "schema": { "type": "string" }, "description": "Shipping city", "example": "Berlin" },
          { "name": "countryCode", "in": "query", "required": true, "schema": { "type": "string" }, "description": "Shipping country (ISO 3166-1 alpha-2)", "example": "DE" },
          { "name": "wantInvoice", "in": "query", "schema": { "type": "string", "enum": ["true", "false"] }, "description": "Request invoice" },
          { "name": "billingLine1", "in": "query", "schema": { "type": "string" }, "description": "Billing street address (if different from shipping)" },
          { "name": "billingPostalCode", "in": "query", "schema": { "type": "string" }, "description": "Billing postal code" },
          { "name": "billingCity", "in": "query", "schema": { "type": "string" }, "description": "Billing city" },
          { "name": "billingCountryCode", "in": "query", "schema": { "type": "string" }, "description": "Billing country code" }
        ],
        "responses": {
          "302": {
            "description": "Redirects to checkout page with cart and address pre-filled"
          },
          "400": {
            "description": "Invalid request — returns plain text error"
          },
          "404": {
            "description": "Product not found"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      },
      "post": {
        "operationId": "buyProduct",
        "summary": "Create a checkout session for a product (JSON API)",
        "description": "Validates product and address, returns checkout page URL as JSON. Shipping costs are calculated dynamically at checkout based on destination — not included in this response. Rate-limited to 10 req/min/IP.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BuyRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Checkout session created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BuyResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (missing product ID, invalid variant, quantity out of range)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Product not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Product or variant currently unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (max 10 requests per minute per IP)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "CatalogIndex": {
        "type": "object",
        "properties": {
          "apiVersion": {
            "type": "string",
            "example": "1.0"
          },
          "defaultLocale": {
            "type": "string",
            "example": "en"
          },
          "locales": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "string",
                  "example": "en"
                },
                "catalogUrl": {
                  "type": "string",
                  "example": "/api/catalog/en.json"
                }
              }
            }
          },
          "buyEndpoint": {
            "type": "string",
            "example": "/api/buy"
          },
          "discovery": {
            "type": "object",
            "properties": {
              "aiPlugin": {
                "type": "string",
                "example": "/.well-known/ai-plugin.json"
              },
              "openapi": {
                "type": "string",
                "example": "/.well-known/openapi.json"
              }
            }
          }
        }
      },
      "Catalog": {
        "type": "object",
        "properties": {
          "apiVersion": {
            "type": "string",
            "example": "1.0"
          },
          "locale": {
            "type": "string",
            "description": "Locale code"
          },
          "availableLocales": {
            "type": "array",
            "items": { "type": "string" },
            "description": "All supported locale codes"
          },
          "currency": {
            "type": "string",
            "example": "EUR"
          },
          "generatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "shipping": {
            "type": "object",
            "description": "Shipping information",
            "properties": {
              "origin": { "type": "string", "example": "IT" },
              "worldwide": { "type": "boolean" },
              "dispatchCutoff": { "type": "string" },
              "estimatedDelivery": {
                "type": "object",
                "properties": {
                  "europe": { "type": "string" },
                  "other": { "type": "string" }
                }
              },
              "costNote": { "type": "string" }
            }
          },
          "tax": {
            "type": "object",
            "description": "Tax/VAT behavior",
            "properties": {
              "behavior": { "type": "string", "example": "exclusive" },
              "note": { "type": "string" }
            }
          },
          "checkoutMode": {
            "type": "string",
            "description": "How checkout works",
            "example": "stripe-hosted"
          },
          "products": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Product"
            }
          },
          "buyEndpoint": {
            "type": "object",
            "description": "Instructions for purchasing a product via the API"
          }
        }
      },
      "Product": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Product identifier — use as productId in buy requests. Canonical, locale-independent.",
            "example": "laptop-stand"
          },
          "name": {
            "type": "string",
            "description": "Localized product name",
            "example": "A Wooden Laptop Stand"
          },
          "description": {
            "type": "string"
          },
          "price": {
            "type": "number",
            "description": "Price in EUR",
            "example": 22.00
          },
          "compareAtPrice": {
            "type": "number",
            "description": "Original price before discount, if applicable"
          },
          "currency": {
            "type": "string",
            "example": "EUR"
          },
          "maxQuantity": {
            "type": "integer",
            "description": "Maximum quantity per order",
            "example": 10
          },
          "inStock": {
            "type": "boolean",
            "description": "Whether the product is currently available for purchase"
          },
          "category": {
            "type": "string"
          },
          "material": {
            "type": "string"
          },
          "dimensions": {
            "type": "string",
            "example": "30.8 × 23.5 × 1.8 cm"
          },
          "weight": {
            "type": "string",
            "example": "0.29 kg"
          },
          "variants": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Variant"
            }
          },
          "images": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "url": {
            "type": "string",
            "description": "Product page URL (locale-aware)"
          },
          "buyUrl": {
            "type": "string",
            "description": "API endpoint for purchasing"
          }
        }
      },
      "Variant": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Variant identifier — use as variantId in buy requests. Canonical, locale-independent.",
            "example": "slim"
          },
          "name": {
            "type": "string",
            "description": "Localized variant name",
            "example": "Slim"
          },
          "sku": {
            "type": "string",
            "example": "STOOD-SLIM"
          },
          "thicknessSpec": {
            "type": "string",
            "example": "Max 2 cm"
          },
          "inStock": {
            "type": "boolean",
            "description": "Whether this variant is currently available"
          }
        }
      },
      "Address": {
        "type": "object",
        "required": ["line1", "postalCode", "city", "countryCode"],
        "properties": {
          "line1": {
            "type": "string",
            "description": "Street address line 1",
            "example": "Hauptstraße 42"
          },
          "line2": {
            "type": "string",
            "description": "Street address line 2 (optional)"
          },
          "postalCode": {
            "type": "string",
            "description": "Postal/ZIP code",
            "example": "10115"
          },
          "city": {
            "type": "string",
            "description": "City",
            "example": "Berlin"
          },
          "countryCode": {
            "type": "string",
            "description": "ISO 3166-1 alpha-2 country code (e.g. DE, IT, US, GB)",
            "example": "DE"
          }
        }
      },
      "BuyRequest": {
        "type": "object",
        "required": ["shippingAddress"],
        "properties": {
          "items": {
            "type": "array",
            "description": "Array of items to purchase (for multi-item orders). Alternative to productId/variantId/quantity.",
            "items": {
              "type": "object",
              "required": ["productId"],
              "properties": {
                "productId": { "type": "string", "description": "Product ID from catalog", "example": "laptop-stand" },
                "variantId": { "type": "string", "description": "Variant ID (required if product has multiple variants)", "example": "slim" },
                "quantity": { "type": "integer", "minimum": 1, "maximum": 10, "default": 1 }
              }
            },
            "example": [{"productId": "laptop-stand", "variantId": "big-boned", "quantity": 1}, {"productId": "laptop-stand", "variantId": "slim", "quantity": 6}]
          },
          "productId": {
            "type": "string",
            "description": "Product ID (single-item shorthand, alternative to items array)",
            "example": "laptop-stand"
          },
          "variantId": {
            "type": "string",
            "description": "Variant ID for single-item shorthand",
            "example": "slim"
          },
          "quantity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 10,
            "default": 1,
            "description": "Quantity for single-item shorthand"
          },
          "locale": {
            "type": "string",
            "enum": ["en", "de", "fr", "it", "es", "nl", "ja", "zh", "ko", "sv"],
            "default": "en",
            "description": "Locale for the checkout experience"
          },
          "shippingAddress": {
            "$ref": "#/components/schemas/Address",
            "description": "Shipping address (required). The checkout page pre-fills the address form and auto-calculates shipping rates. Without a shipping address, the purchase cannot be completed."
          },
          "billingAddress": {
            "$ref": "#/components/schemas/Address",
            "description": "Optional billing address. Only needed when wantInvoice is true and billing differs from shipping. If omitted with wantInvoice, shipping address is used for billing."
          },
          "wantInvoice": {
            "type": "boolean",
            "default": false,
            "description": "Set to true if the customer wants an invoice emailed after payment. When true, billing address is used (falls back to shipping address if billingAddress is not provided)."
          }
        }
      },
      "BuyResponse": {
        "type": "object",
        "properties": {
          "checkoutUrl": {
            "type": "string",
            "description": "Checkout page URL with cart pre-populated. Redirect the customer here to enter their shipping address, see shipping rates, and complete payment via Stripe.",
            "example": "https://stood.it/checkout?buyNow=eyJpZCI6..."
          },
          "requestId": {
            "type": "string",
            "description": "Unique request identifier for support and debugging.",
            "example": "buy_m1abc_x7k2f3"
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Error message"
          },
          "requestId": {
            "type": "string",
            "description": "Unique request identifier"
          },
          "inStock": {
            "type": "boolean",
            "description": "Present and false when product/variant is unavailable"
          },
          "availableVariants": {
            "type": "array",
            "description": "Available variants (included when variant selection is needed)",
            "items": {
              "type": "object",
              "properties": {
                "id": { "type": "string" },
                "name": { "type": "string" }
              }
            }
          }
        }
      }
    }
  }
}
