{
  "openapi": "3.0.1",
  "info": {
    "title": "QRCodeCrafter API",
    "version": "1.0.0",
    "description": "Generate branded static QR codes in SVG, PNG, JPG, WebP, PDF, or EPS via the QR Code Crafter service.",
    "termsOfService": "https://qrcodecrafter.com/terms",
    "contact": {
      "name": "QR Code Crafter Agent Support",
      "email": "support@qrcodecrafter.com"
    }
  },
  "servers": [
    {
      "url": "https://qrcodecrafter.com",
      "description": "Production"
    }
  ],
  "x-agent-workflows": {
    "dynamicQrCampaign": {
      "description": "Create one to five dynamic QR redirects sequentially. Each row uses createDynamicQr; retain successful one-time management capabilities even when a later row fails. Do not retry a successful row automatically.",
      "runtimeTool": "create_dynamic_qr_campaign",
      "visibleFormTool": "create_dynamic_qr_campaign_pack",
      "maxRows": 5,
      "assetWorkflow": "Call generateQr for each successful redirectUrl, or use the visible browser workflow to download one private ZIP with QR assets and JSON/CSV capability manifests.",
      "privacy": "Management URLs and tokens are unrecoverable secrets. Never publish the manifest or include management capabilities in QR artwork."
    }
  },
  "paths": {
    "/.netlify/functions/generate-qr": {
      "get": {
        "summary": "Download a QR code asset via Netlify Function",
        "operationId": "downloadQr",
        "security": [
          {
            "AgentApiKey": []
          },
          {}
        ],
        "parameters": [
          {
            "name": "value",
            "in": "query",
            "required": true,
            "description": "Text, URL, or payload encoded in the QR code",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "format",
            "in": "query",
            "description": "Output format for the QR code asset",
            "schema": {
              "type": "string",
              "enum": [
                "svg",
                "png",
                "jpg",
                "webp",
                "pdf",
                "eps"
              ],
              "default": "png"
            }
          },
          {
            "name": "size",
            "in": "query",
            "description": "Width and height of the generated asset in pixels",
            "schema": {
              "type": "integer",
              "minimum": 256,
              "maximum": 4096
            }
          },
          {
            "name": "margin",
            "in": "query",
            "description": "Quiet-zone margin around the QR code modules",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 16
            }
          },
          {
            "name": "bgColor",
            "in": "query",
            "description": "Background color in hex format, for example #FFFFFF",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fgColor",
            "in": "query",
            "description": "Foreground color in hex format, for example #000000",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "errorCorrectionLevel",
            "in": "query",
            "description": "Error correction level for QR encoding",
            "schema": {
              "type": "string",
              "enum": [
                "L",
                "M",
                "Q",
                "H"
              ]
            }
          },
          {
            "name": "logo",
            "in": "query",
            "description": "Optional base64 PNG, JPG, or WebP data URL for an embedded logo",
            "schema": {
              "type": "string",
              "nullable": true,
              "maxLength": 1500000,
              "pattern": "^data:image\\/(png|jpe?g|webp);base64,.+"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Generated QR code asset served as binary content",
            "headers": {
              "X-QR-Width": {
                "description": "Rendered asset width",
                "schema": {
                  "type": "number"
                }
              },
              "X-QR-Height": {
                "description": "Rendered asset height",
                "schema": {
                  "type": "number"
                }
              },
              "X-QR-Unit": {
                "description": "Dimension unit, px for SVG/raster and pt for PDF/EPS",
                "schema": {
                  "type": "string",
                  "enum": [
                    "px",
                    "pt"
                  ]
                }
              },
              "X-QR-Bytes": {
                "description": "Exact number of decoded asset bytes",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "image/svg+xml": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "image/png": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "image/jpeg": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "image/webp": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/postscript": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key when key enforcement is enabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. QR generation uses a cost-weighted per-client budget; honor the retry and rate-limit headers before resubmitting work.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Cost budget units available in the current window for this client class",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Cost budget units remaining in the current window",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Generate a QR code asset via Netlify Function",
        "operationId": "generateQr",
        "security": [
          {
            "AgentApiKey": []
          },
          {}
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GenerateQrRequest"
              },
              "examples": {
                "urlSvg": {
                  "summary": "URL QR code as SVG",
                  "value": {
                    "value": "https://example.com/menu?utm_source=qr&utm_medium=table_tent",
                    "format": "svg",
                    "size": 1024,
                    "margin": 4,
                    "fgColor": "#111111",
                    "bgColor": "#ffffff",
                    "errorCorrectionLevel": "H"
                  }
                },
                "textWebp": {
                  "summary": "Plain text QR code as WebP",
                  "value": {
                    "value": "Order #A-12345 | Table 7 | Save 15% with code QR15.",
                    "format": "webp",
                    "size": 1024,
                    "margin": 4
                  }
                },
                "wifiPng": {
                  "summary": "Wi-Fi QR code as PNG",
                  "value": {
                    "value": "WIFI:T:WPA;S:Guest Network;P:Welcome123;H:false;;",
                    "format": "png",
                    "size": 1024,
                    "margin": 4,
                    "errorCorrectionLevel": "H"
                  }
                },
                "emailJpg": {
                  "summary": "Email action QR code as JPG",
                  "value": {
                    "value": "mailto:support@example.com?subject=QR%20support&body=Please%20contact%20me",
                    "format": "jpg",
                    "size": 1024,
                    "margin": 4
                  }
                },
                "smsSvg": {
                  "summary": "SMS QR code as SVG",
                  "value": {
                    "value": "SMSTO:+15551234567:QR smoke test",
                    "format": "svg",
                    "size": 1024,
                    "margin": 4
                  }
                },
                "phoneSvg": {
                  "summary": "Phone call QR code as SVG",
                  "value": {
                    "value": "tel:+15551234567",
                    "format": "svg",
                    "size": 1024,
                    "margin": 4
                  }
                },
                "whatsappPng": {
                  "summary": "WhatsApp chat QR code as PNG",
                  "value": {
                    "value": "https://wa.me/15551234567?text=QR%20smoke%20test",
                    "format": "png",
                    "size": 1024,
                    "margin": 4
                  }
                },
                "vcardPdf": {
                  "summary": "vCard QR code as PDF",
                  "value": {
                    "value": "BEGIN:VCARD\nVERSION:3.0\nFN:Jordan Smith\nTEL:+15558675309\nEMAIL:hello@example.com\nEND:VCARD",
                    "format": "pdf",
                    "size": 1024,
                    "margin": 4
                  }
                },
                "eventSvg": {
                  "summary": "Calendar event QR code as SVG",
                  "value": {
                    "value": "BEGIN:VCALENDAR\nVERSION:2.0\nBEGIN:VEVENT\nSUMMARY:Product Demo\nDTSTART:20300601T100000\nDTEND:20300601T110000\nLOCATION:Online\nURL:https://example.com/demo\nEND:VEVENT\nEND:VCALENDAR",
                    "format": "svg",
                    "size": 1024,
                    "margin": 4
                  }
                },
                "locationPng": {
                  "summary": "Location QR code as PNG",
                  "value": {
                    "value": "geo:37.422,-122.084?q=1600%20Amphitheatre%20Parkway",
                    "format": "png",
                    "size": 1024,
                    "margin": 4
                  }
                },
                "cryptoSvg": {
                  "summary": "Bitcoin payment QR code as SVG",
                  "value": {
                    "value": "bitcoin:bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kygt080?amount=0.01",
                    "format": "svg",
                    "size": 1024,
                    "margin": 4
                  }
                },
                "pixEps": {
                  "summary": "PIX payment QR code as EPS",
                  "value": {
                    "value": "00020101021126510014BR.GOV.BCB.PIX0117smoke@example.com0208SMOKE12352040000530398654041.235802BR5910SMOKE TEST6009SAO PAULO62120508SMOKE12363047B22",
                    "format": "eps",
                    "size": 1024,
                    "margin": 4
                  }
                },
                "upiPdf": {
                  "summary": "UPI payment QR code as PDF",
                  "value": {
                    "value": "upi://pay?pa=merchant@upi&pn=Merchant&am=10.00&cu=INR&tn=Invoice",
                    "format": "pdf",
                    "size": 1024,
                    "margin": 4
                  }
                },
                "swishPdf": {
                  "summary": "Swish payment QR code as PDF",
                  "value": {
                    "value": "C1234567890;125,50;Invoice%20123;0",
                    "format": "pdf",
                    "size": 1024,
                    "margin": 4
                  }
                },
                "sepaPdf": {
                  "summary": "SEPA credit transfer QR code as PDF",
                  "value": {
                    "value": "BCD\n002\n1\nSCT\nCOBADEFFXXX\nSmoke Test GmbH\nDE89370400440532013000\nEUR49.90\n\nINV-2026-001",
                    "format": "pdf",
                    "size": 1024,
                    "margin": 4
                  }
                },
                "paypalSvg": {
                  "summary": "PayPal.Me payment QR code as SVG",
                  "value": {
                    "value": "https://paypal.me/qrcodecrafter/25USD",
                    "format": "svg",
                    "size": 1024,
                    "margin": 4
                  }
                },
                "venmoSvg": {
                  "summary": "Venmo profile QR code as SVG",
                  "value": {
                    "value": "https://venmo.com/u/qrcodecrafter",
                    "format": "svg",
                    "size": 1024,
                    "margin": 4
                  }
                },
                "cashAppSvg": {
                  "summary": "Cash App $Cashtag QR code as SVG",
                  "value": {
                    "value": "https://cash.app/$qrcodecrafter",
                    "format": "svg",
                    "size": 1024,
                    "margin": 4
                  }
                },
                "promptPaySvg": {
                  "summary": "PromptPay payment QR code as SVG",
                  "value": {
                    "value": "00020101021229370016A000000677010111011300668123456785802TH53037645406125.5063047652",
                    "format": "svg",
                    "size": 1024,
                    "margin": 4
                  }
                },
                "vietQrSvg": {
                  "summary": "VietQR bank transfer QR code as SVG",
                  "value": {
                    "value": "00020101021238560010A0000007270126000697041501121133666688880208QRIBFTTA530370454061500005802VN62100806INV123630421F5",
                    "format": "svg",
                    "size": 1024,
                    "margin": 4
                  }
                },
                "appStoreSvg": {
                  "summary": "App Store QR code as SVG",
                  "value": {
                    "value": "https://apps.apple.com/app/id1234567890?pt=123456&ct=qr_campaign&mt=8",
                    "format": "svg",
                    "size": 1024,
                    "margin": 4
                  }
                },
                "socialProfilePng": {
                  "summary": "Social profile QR code as PNG",
                  "value": {
                    "value": "https://www.instagram.com/qrcodecrafter",
                    "format": "png",
                    "size": 1024,
                    "margin": 4
                  }
                },
                "brandedLogoPng": {
                  "summary": "Branded URL QR code with PNG logo",
                  "value": {
                    "value": "https://example.com/landing",
                    "format": "png",
                    "size": 1024,
                    "margin": 4,
                    "fgColor": "#111111",
                    "bgColor": "#ffffff",
                    "errorCorrectionLevel": "H",
                    "logo": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+/p9sAAAAASUVORK5CYII="
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Generated QR code asset encoded as base64",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GenerateQrResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key when key enforcement is enabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. QR generation uses a cost-weighted per-client budget; honor the retry and rate-limit headers before resubmitting work.",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Cost budget units available in the current window for this client class",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Cost budget units remaining in the current window",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/.netlify/functions/generate-qr-bulk": {
      "post": {
        "summary": "Generate a ZIP archive of static QR code files",
        "operationId": "generateBulkQr",
        "description": "Create a ZIP archive containing up to 50 static QR code assets plus manifest.csv and manifest.json. Use this for spreadsheet, label, classroom, packaging, and agent batch workflows. The endpoint uses the same QR validation, optional API key, security headers, and cost-weighted rate-limit model as the single-code generator.",
        "security": [
          {
            "AgentApiKey": []
          },
          {}
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GenerateBulkQrRequest"
              },
              "examples": {
                "csvRows": {
                  "summary": "CSV rows into an SVG ZIP",
                  "value": {
                    "rows": "filename,value\nhomepage,https://example.com\nsupport,mailto:support@example.com",
                    "format": "svg",
                    "size": 1024,
                    "margin": 4,
                    "fgColor": "#111111",
                    "bgColor": "#ffffff",
                    "errorCorrectionLevel": "H"
                  }
                },
                "objectRows": {
                  "summary": "Object rows into a PNG ZIP",
                  "value": {
                    "rows": [
                      {
                        "filename": "table-1",
                        "value": "https://example.com/menu?table=1"
                      },
                      {
                        "filename": "table-2",
                        "value": "https://example.com/menu?table=2"
                      }
                    ],
                    "format": "png",
                    "size": 1024,
                    "margin": 4
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Generated ZIP archive returned as JSON or binary ZIP when Accept includes application/zip",
            "headers": {
              "X-Bulk-QR-Files": {
                "description": "Number of QR files generated in the ZIP",
                "schema": {
                  "type": "string"
                }
              },
              "X-Bulk-QR-Bytes": {
                "description": "Exact ZIP byte length",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GenerateBulkQrResponse"
                }
              },
              "application/zip": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "description": "Invalid batch request or row data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key when key enforcement is enabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Batch request or generated ZIP is too large",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Batch cost exceeds the current rate-limit budget or generation is rate limited",
            "headers": {
              "Retry-After": {
                "description": "Number of seconds to wait before retrying the request",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Cost budget units available in the current window for this client class",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Cost budget units remaining in the current window",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "No QR files could be generated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/send-feedback": {
      "post": {
        "summary": "Send user feedback",
        "operationId": "sendFeedback",
        "security": [
          {
            "AgentApiKey": []
          },
          {}
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string"
                  },
                  "message": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Feedback logged",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key when key enforcement is enabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/dynamic-qr": {
      "post": {
        "summary": "Create a private dynamic QR redirect",
        "operationId": "createDynamicQr",
        "description": "Creates an editable HTTPS destination. The management token is returned only in this response; store it as a secret capability.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DynamicQrCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Dynamic QR record created. Optional analytics retain only aggregate redirect counts and no visitor identifiers.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Dynamic-QR-Version": {
                "$ref": "#/components/headers/DynamicQrVersion"
              },
              "Location": {
                "description": "Canonical management API resource URL. The capability token is never included in response headers.",
                "schema": {
                  "type": "string",
                  "format": "uri"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DynamicQrCreateResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid JSON, unsupported fields, unsafe destination, or invalid label",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Cross-origin management write rejected",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Create rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Dynamic QR storage unavailable or the hard active-record capacity has been reached",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/dynamic-qr/{slug}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DynamicQrSlug"
        }
      ],
      "get": {
        "summary": "Read a dynamic QR record",
        "operationId": "getDynamicQr",
        "security": [
          {
            "DynamicQrBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Authorized dynamic QR record",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Dynamic-QR-Version": {
                "$ref": "#/components/headers/DynamicQrVersion"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DynamicQrManageResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or invalid capability token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Dynamic QR storage unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "summary": "Update a dynamic QR record",
        "operationId": "updateDynamicQr",
        "security": [
          {
            "DynamicQrBearer": []
          }
        ],
        "description": "Requires the current ETag in If-Match. Set rotateToken to true to replace the bearer capability; the old token is immediately invalid.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IfMatch"
          },
          {
            "$ref": "#/components/parameters/DynamicQrVersionMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DynamicQrUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated dynamic QR record",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Dynamic-QR-Version": {
                "$ref": "#/components/headers/DynamicQrVersion"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DynamicQrUpdateResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid JSON or update fields",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or invalid capability token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Cross-origin management write rejected",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "412": {
            "description": "Missing or stale If-Match ETag",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "423": {
            "description": "The record is operator-blocked and cannot be updated or resumed by its capability holder",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Dynamic QR storage unavailable; no record was changed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Permanently delete a dynamic QR record",
        "operationId": "deleteDynamicQr",
        "security": [
          {
            "DynamicQrBearer": []
          }
        ],
        "description": "Requires the current ETag in If-Match. Deletion is irreversible and the printed redirect URL will return 404.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IfMatch"
          },
          {
            "$ref": "#/components/parameters/DynamicQrVersionMatch"
          }
        ],
        "responses": {
          "204": {
            "description": "Dynamic QR record permanently deleted"
          },
          "401": {
            "description": "Missing, malformed, or invalid capability token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Cross-origin management write rejected",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "412": {
            "description": "Missing or stale If-Match ETag",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Management rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Dynamic QR storage unavailable; deletion was not confirmed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/dynamic-qr-vaults": {
      "post": {
        "summary": "Create a capability-managed dynamic QR vault",
        "operationId": "createDynamicQrVault",
        "description": "Creates a private no-account vault for up to 50 project-owned redirects. The vault management token is returned only by this operation and is never recoverable.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DynamicQrVaultCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Vault created with its one-time bearer capability",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Dynamic-QR-Vault-Version": {
                "$ref": "#/components/headers/DynamicQrVaultVersion"
              },
              "Location": {
                "schema": {
                  "type": "string",
                  "format": "uri"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DynamicQrVaultCreateResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid JSON",
            "name": null,
            "or unsupported field": null,
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Cross-origin write rejected",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Vault storage unavailable or at capacity",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/dynamic-qr-vaults/{vaultId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DynamicQrVaultId"
        }
      ],
      "get": {
        "summary": "Read an authorized dynamic QR vault and its public child records",
        "operationId": "getDynamicQrVault",
        "security": [
          {
            "DynamicQrVaultBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Vault and project-owned records; never includes token hashes or child management credentials",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Dynamic-QR-Vault-Version": {
                "$ref": "#/components/headers/DynamicQrVaultVersion"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DynamicQrVaultResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing",
            "malformed": null,
            "unknown": null,
            "or invalid vault capability": null,
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "summary": "Rename a dynamic QR vault",
        "operationId": "updateDynamicQrVault",
        "description": "Requires the current vault ETag in If-Match or X-Dynamic-QR-Vault-Version.",
        "security": [
          {
            "DynamicQrVaultBearer": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IfMatch"
          },
          {
            "$ref": "#/components/parameters/DynamicQrVaultVersionMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DynamicQrVaultRenameRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Renamed vault",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Dynamic-QR-Vault-Version": {
                "$ref": "#/components/headers/DynamicQrVaultVersion"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DynamicQrVaultResponse"
                }
              }
            }
          },
          "401": {
            "description": "Invalid vault capability",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "412": {
            "description": "Missing or stale vault ETag",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete an empty dynamic QR vault",
        "operationId": "deleteDynamicQrVault",
        "description": "Requires the current vault ETag. Deletion is non-cascading and fails while the vault contains child records.",
        "security": [
          {
            "DynamicQrVaultBearer": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IfMatch"
          },
          {
            "$ref": "#/components/parameters/DynamicQrVaultVersionMatch"
          }
        ],
        "responses": {
          "204": {
            "description": "Empty vault permanently deleted"
          },
          "401": {
            "description": "Invalid vault capability",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Vault is not empty",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "412": {
            "description": "Missing or stale vault ETag",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/dynamic-qr-vaults/{vaultId}/qr": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DynamicQrVaultId"
        }
      ],
      "post": {
        "summary": "Create a project-owned dynamic QR record",
        "operationId": "createDynamicQrVaultChild",
        "description": "Requires the current vault ETag. The child is controlled only by the vault capability; no child token or token hash is returned.",
        "security": [
          {
            "DynamicQrVaultBearer": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IfMatch"
          },
          {
            "$ref": "#/components/parameters/DynamicQrVaultVersionMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DynamicQrVaultChildCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Project-owned child created",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Dynamic-QR-Version": {
                "$ref": "#/components/headers/DynamicQrVersion"
              },
              "X-Dynamic-QR-Vault-Version": {
                "$ref": "#/components/headers/DynamicQrVaultVersion"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DynamicQrVaultChildResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid destination or metadata",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid vault capability",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "412": {
            "description": "Missing or stale vault ETag",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/dynamic-qr-vaults/{vaultId}/qr/{slug}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DynamicQrVaultId"
        },
        {
          "$ref": "#/components/parameters/DynamicQrSlug"
        }
      ],
      "patch": {
        "summary": "Update, pause, or resume a project-owned dynamic QR record",
        "operationId": "updateDynamicQrVaultChild",
        "description": "Requires the current child ETag in If-Match or X-Dynamic-QR-Version. The vault version is returned separately when successful.",
        "security": [
          {
            "DynamicQrVaultBearer": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IfMatch"
          },
          {
            "$ref": "#/components/parameters/DynamicQrVersionMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DynamicQrVaultChildUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated public child record without internal ownership or credentials",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Dynamic-QR-Version": {
                "$ref": "#/components/headers/DynamicQrVersion"
              },
              "X-Dynamic-QR-Vault-Version": {
                "$ref": "#/components/headers/DynamicQrVaultVersion"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DynamicQrVaultChildResponse"
                }
              }
            }
          },
          "401": {
            "description": "Invalid vault capability",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Child is not owned by this vault",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "412": {
            "description": "Missing or stale child ETag",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/dynamic-qr-vaults/{vaultId}/qr/{slug}/analytics": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DynamicQrVaultId"
        },
        {
          "$ref": "#/components/parameters/DynamicQrSlug"
        }
      ],
      "get": {
        "summary": "Read aggregate analytics for one project-owned dynamic QR record",
        "operationId": "getDynamicQrVaultChildAnalytics",
        "description": "Requires the private vault bearer capability and verifies that the selected child belongs to the vault. Returns approximate aggregate redirect counts only; no visitor identifiers, IP addresses, user agents, referrers, cookies, locations, or device data are stored.",
        "security": [
          {
            "DynamicQrVaultBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Aggregate analytics for the selected project-owned redirect. Analytics may be omitted when disabled outside production.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DynamicQrVaultChildAnalyticsResponse"
                }
              }
            }
          },
          "401": {
            "description": "Invalid vault capability",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Child is not owned by this vault",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Vault or child storage temporarily unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Permanently delete a project-owned dynamic QR record",
        "operationId": "deleteDynamicQrVaultChild",
        "description": "Requires the current child ETag. Deletion also removes vault membership and returns the new vault validator.",
        "security": [
          {
            "DynamicQrVaultBearer": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IfMatch"
          },
          {
            "$ref": "#/components/parameters/DynamicQrVersionMatch"
          }
        ],
        "responses": {
          "204": {
            "description": "Child permanently deleted",
            "headers": {
              "X-Dynamic-QR-Vault-Version": {
                "$ref": "#/components/headers/DynamicQrVaultVersion"
              }
            }
          },
          "401": {
            "description": "Invalid vault capability",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Child is not owned by this vault",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "412": {
            "description": "Missing or stale child ETag",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/r/{slug}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DynamicQrSlug"
        }
      ],
      "get": {
        "summary": "Redirect a dynamic QR scan",
        "operationId": "redirectDynamicQr",
        "description": "Public redirect. When aggregate analytics are enabled, only the slug and UTC count bucket are retained; no IP address, user agent, referrer, cookie, location, device data, or tracking parameter is stored.",
        "responses": {
          "302": {
            "description": "Active destination redirect",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string",
                  "format": "uri"
                }
              }
            }
          },
          "404": {
            "description": "Dynamic QR slug not found"
          },
          "405": {
            "description": "Method not allowed"
          },
          "410": {
            "description": "Dynamic QR destination is owner-paused or operator-blocked"
          },
          "429": {
            "description": "Redirect traffic rate limit exceeded"
          },
          "503": {
            "description": "Redirect storage unavailable",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "head": {
        "summary": "Check a dynamic QR redirect without a response body",
        "operationId": "headDynamicQr",
        "description": "Returns the same status and Location headers as GET without a response body.",
        "responses": {
          "302": {
            "description": "Active destination redirect",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string",
                  "format": "uri"
                }
              }
            }
          },
          "404": {
            "description": "Dynamic QR slug not found"
          },
          "410": {
            "description": "Dynamic QR destination is owner-paused or operator-blocked"
          },
          "429": {
            "description": "Redirect traffic rate limit exceeded"
          },
          "503": {
            "description": "Redirect storage unavailable"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "GenerateQrRequest": {
        "type": "object",
        "required": [
          "value"
        ],
        "x-agent-supported-content-types": [
          "url",
          "appstore",
          "social",
          "text",
          "wifi",
          "email",
          "sms",
          "phone",
          "whatsapp",
          "vcard",
          "event",
          "location",
          "crypto",
          "pix",
          "upi",
          "phonepe",
          "swish",
          "sepa",
          "ideal",
          "mobilepayvipps",
          "qris",
          "paypal",
          "venmo",
          "cashapp",
          "promptpay",
          "vietqr",
          "swissqr"
        ],
        "x-agent-rate-limit": {
          "model": "cost-weighted per client",
          "windowSeconds": 60,
          "defaultBudgetUnits": 180,
          "authenticatedBudgetUnits": 600,
          "retryHeaders": [
            "Retry-After",
            "X-RateLimit-Limit",
            "X-RateLimit-Remaining"
          ],
          "costUnits": {
            "svg": 1,
            "png": 3,
            "jpg": 4,
            "webp": 4,
            "pdf": 6,
            "eps": 3,
            "logo": 4,
            "sizeOver2048": 2,
            "sizeOver3072": 4
          },
          "guidance": "Prefer SVG for high-volume tests, throttle batch jobs, and honor Retry-After before retrying 429 or 503 responses."
        },
        "x-agent-payload-patterns": {
          "url": "https://example.com/path?utm_source=qr&utm_medium=print",
          "appstore": "https://apps.apple.com/app/id1234567890",
          "social": "https://www.instagram.com/qrcodecrafter",
          "text": "Short public text only",
          "wifi": "WIFI:T:WPA;S:Network Name;P:Password;H:false;;",
          "email": "mailto:hello@example.com?subject=Subject&body=Message",
          "sms": "SMSTO:+15551234567:Message",
          "phone": "tel:+15551234567",
          "whatsapp": "https://wa.me/15551234567?text=Message",
          "vcard": "BEGIN:VCARD\\nVERSION:3.0\\nFN:Name\\nTEL:+15551234567\\nEMAIL:hello@example.com\\nEND:VCARD",
          "event": "BEGIN:VCALENDAR\\nVERSION:2.0\\nBEGIN:VEVENT\\nSUMMARY:Event\\nDTSTART:20300601T100000\\nEND:VEVENT\\nEND:VCALENDAR",
          "location": "geo:37.422,-122.084?q=1600%20Amphitheatre%20Parkway",
          "crypto": "bitcoin:bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kygt080?amount=0.01",
          "pix": "00020101021126510014BR.GOV.BCB.PIX0117smoke@example.com0208SMOKE12352040000530398654041.235802BR5910SMOKE TEST6009SAO PAULO62120508SMOKE12363047B22",
          "upi": "upi://pay?pa=merchant@upi&pn=Merchant&am=10.00&cu=INR",
          "phonepe": "upi://pay?pa=phonepe-merchant@upi&pn=PhonePe%20Merchant&am=10.00&cu=INR&tn=Invoice",
          "swish": "C1234567890;125,50;Invoice%20123;0",
          "sepa": "BCD\\n002\\n1\\nSCT\\nCOBADEFFXXX\\nSmoke Test GmbH\\nDE89370400440532013000\\nEUR49.90\\n\\nINV-2026-001",
          "ideal": "https://pay.example.nl/ideal/invoice-2026-001",
          "mobilepayvipps": "https://pay.example.com/mobilepay-vipps/invoice-2026-001",
          "qris": "https://merchant.example.co.id/qris/invoice-2026-001",
          "paypal": "https://paypal.me/qrcodecrafter/25USD",
          "venmo": "https://venmo.com/u/qrcodecrafter",
          "cashapp": "https://cash.app/$qrcodecrafter",
          "promptpay": "00020101021229370016A000000677010111011300668123456785802TH53037645406125.5063047652",
          "vietqr": "00020101021238560010A0000007270126000697041501121133666688880208QRIBFTTA530370454061500005802VN62100806INV123630421F5",
          "swissqr": "SPC\\n0200\\n1\\nCH9300762011623852957\\nS\\nRobert Schneider AG\\nRue du Lac\\n1268\\n2501\\nBiel\\nCH\\n\\n\\n\\n\\n\\n\\n\\n199.95\\nCHF\\n\\n\\n\\n\\n\\n\\n\\nNON\\n\\nInvoice 2026-001\\nEPD\\n\\n\\n"
        },
        "x-agent-recipes": {
          "url": {
            "label": "Campaign landing page",
            "bestFormats": [
              "svg",
              "pdf",
              "png"
            ],
            "request": {
              "value": "https://example.com/path?utm_source=qr&utm_medium=print&utm_campaign=spring",
              "format": "svg",
              "size": 1024,
              "margin": 4,
              "fgColor": "#111111",
              "bgColor": "#ffffff",
              "errorCorrectionLevel": "H"
            }
          },
          "appstore": {
            "label": "App download page",
            "bestFormats": [
              "svg",
              "png",
              "pdf"
            ],
            "request": {
              "value": "https://apps.apple.com/app/id1234567890?pt=123456&ct=qr_campaign&mt=8",
              "format": "svg",
              "size": 1024,
              "margin": 4,
              "fgColor": "#111111",
              "bgColor": "#ffffff",
              "errorCorrectionLevel": "H"
            }
          },
          "social": {
            "label": "Social profile",
            "bestFormats": [
              "png",
              "svg",
              "webp"
            ],
            "request": {
              "value": "https://www.instagram.com/qrcodecrafter",
              "format": "png",
              "size": 1024,
              "margin": 4,
              "fgColor": "#111111",
              "bgColor": "#ffffff",
              "errorCorrectionLevel": "H"
            }
          },
          "text": {
            "label": "Public text note",
            "bestFormats": [
              "png",
              "svg",
              "webp"
            ],
            "request": {
              "value": "Order #A-12345 | Table 7 | Save 15% with code QR15.",
              "format": "png",
              "size": 1024,
              "margin": 4,
              "fgColor": "#111111",
              "bgColor": "#ffffff",
              "errorCorrectionLevel": "H"
            }
          },
          "wifi": {
            "label": "Guest Wi-Fi login",
            "bestFormats": [
              "svg",
              "png",
              "pdf"
            ],
            "request": {
              "value": "WIFI:T:WPA;S:Guest Network;P:Welcome123;H:false;;",
              "format": "svg",
              "size": 1024,
              "margin": 4,
              "fgColor": "#111111",
              "bgColor": "#ffffff",
              "errorCorrectionLevel": "H"
            }
          },
          "email": {
            "label": "Prefilled email action",
            "bestFormats": [
              "svg",
              "png",
              "jpg"
            ],
            "request": {
              "value": "mailto:support@example.com?subject=QR%20support&body=Please%20contact%20me",
              "format": "svg",
              "size": 1024,
              "margin": 4,
              "fgColor": "#111111",
              "bgColor": "#ffffff",
              "errorCorrectionLevel": "H"
            }
          },
          "sms": {
            "label": "Prefilled SMS action",
            "bestFormats": [
              "svg",
              "png",
              "jpg"
            ],
            "request": {
              "value": "SMSTO:+15551234567:QR smoke test",
              "format": "svg",
              "size": 1024,
              "margin": 4,
              "fgColor": "#111111",
              "bgColor": "#ffffff",
              "errorCorrectionLevel": "H"
            }
          },
          "phone": {
            "label": "Tap-to-call phone number",
            "bestFormats": [
              "svg",
              "png",
              "jpg"
            ],
            "request": {
              "value": "tel:+15551234567",
              "format": "svg",
              "size": 1024,
              "margin": 4,
              "fgColor": "#111111",
              "bgColor": "#ffffff",
              "errorCorrectionLevel": "H"
            }
          },
          "whatsapp": {
            "label": "WhatsApp chat link",
            "bestFormats": [
              "png",
              "svg",
              "webp"
            ],
            "request": {
              "value": "https://wa.me/15551234567?text=QR%20smoke%20test",
              "format": "png",
              "size": 1024,
              "margin": 4,
              "fgColor": "#111111",
              "bgColor": "#ffffff",
              "errorCorrectionLevel": "H"
            }
          },
          "vcard": {
            "label": "Contact card",
            "bestFormats": [
              "pdf",
              "svg",
              "png"
            ],
            "request": {
              "value": "BEGIN:VCARD\nVERSION:3.0\nFN:Jordan Smith\nTEL:+15558675309\nEMAIL:hello@example.com\nEND:VCARD",
              "format": "pdf",
              "size": 1024,
              "margin": 4,
              "fgColor": "#111111",
              "bgColor": "#ffffff",
              "errorCorrectionLevel": "H"
            }
          },
          "event": {
            "label": "Calendar invite",
            "bestFormats": [
              "svg",
              "png",
              "pdf"
            ],
            "request": {
              "value": "BEGIN:VCALENDAR\nVERSION:2.0\nBEGIN:VEVENT\nSUMMARY:Product Demo\nDTSTART:20300601T100000\nDTEND:20300601T110000\nLOCATION:Online\nURL:https://example.com/demo\nEND:VEVENT\nEND:VCALENDAR",
              "format": "svg",
              "size": 1024,
              "margin": 4,
              "fgColor": "#111111",
              "bgColor": "#ffffff",
              "errorCorrectionLevel": "H"
            }
          },
          "location": {
            "label": "Map location",
            "bestFormats": [
              "png",
              "svg",
              "pdf"
            ],
            "request": {
              "value": "geo:37.422,-122.084?q=1600%20Amphitheatre%20Parkway",
              "format": "png",
              "size": 1024,
              "margin": 4,
              "fgColor": "#111111",
              "bgColor": "#ffffff",
              "errorCorrectionLevel": "H"
            }
          },
          "crypto": {
            "label": "Bitcoin payment URI",
            "bestFormats": [
              "svg",
              "png",
              "pdf"
            ],
            "request": {
              "value": "bitcoin:bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kygt080?amount=0.01",
              "format": "svg",
              "size": 1024,
              "margin": 4,
              "fgColor": "#111111",
              "bgColor": "#ffffff",
              "errorCorrectionLevel": "H"
            }
          },
          "pix": {
            "label": "Brazil PIX payment",
            "bestFormats": [
              "eps",
              "pdf",
              "png"
            ],
            "request": {
              "value": "00020101021126510014BR.GOV.BCB.PIX0117smoke@example.com0208SMOKE12352040000530398654041.235802BR5910SMOKE TEST6009SAO PAULO62120508SMOKE12363047B22",
              "format": "eps",
              "size": 1024,
              "margin": 4,
              "fgColor": "#111111",
              "bgColor": "#ffffff",
              "errorCorrectionLevel": "H"
            }
          },
          "upi": {
            "label": "India UPI payment",
            "bestFormats": [
              "pdf",
              "svg",
              "png"
            ],
            "request": {
              "value": "upi://pay?pa=merchant@upi&pn=Merchant&am=10.00&cu=INR&tn=Invoice",
              "format": "pdf",
              "size": 1024,
              "margin": 4,
              "fgColor": "#111111",
              "bgColor": "#ffffff",
              "errorCorrectionLevel": "H"
            }
          },
          "phonepe": {
            "label": "PhonePe-compatible UPI payment",
            "bestFormats": [
              "pdf",
              "svg",
              "png"
            ],
            "request": {
              "value": "upi://pay?pa=phonepe-merchant@upi&pn=PhonePe%20Merchant&am=10.00&cu=INR&tn=Invoice",
              "format": "pdf",
              "size": 1024,
              "margin": 4,
              "fgColor": "#111111",
              "bgColor": "#ffffff",
              "errorCorrectionLevel": "H"
            }
          },
          "swish": {
            "label": "Sweden Swish payment",
            "bestFormats": [
              "pdf",
              "svg",
              "png"
            ],
            "request": {
              "value": "C1234567890;125,50;Invoice%20123;0",
              "format": "pdf",
              "size": 1024,
              "margin": 4,
              "fgColor": "#111111",
              "bgColor": "#ffffff",
              "errorCorrectionLevel": "H"
            }
          },
          "sepa": {
            "label": "SEPA credit transfer payment",
            "bestFormats": [
              "pdf",
              "svg",
              "png"
            ],
            "request": {
              "value": "BCD\n002\n1\nSCT\nCOBADEFFXXX\nSmoke Test GmbH\nDE89370400440532013000\nEUR49.90\n\nINV-2026-001",
              "format": "pdf",
              "size": 1024,
              "margin": 4,
              "fgColor": "#111111",
              "bgColor": "#ffffff",
              "errorCorrectionLevel": "H"
            }
          },
          "ideal": {
            "label": "iDEAL provider payment link",
            "bestFormats": [
              "svg",
              "png",
              "pdf"
            ],
            "request": {
              "value": "https://pay.example.nl/ideal/invoice-2026-001",
              "format": "svg",
              "size": 1024,
              "margin": 4,
              "fgColor": "#111111",
              "bgColor": "#ffffff",
              "errorCorrectionLevel": "H"
            }
          },
          "mobilepayvipps": {
            "label": "MobilePay/Vipps provider payment link",
            "bestFormats": [
              "svg",
              "png",
              "pdf"
            ],
            "request": {
              "value": "https://pay.example.com/mobilepay-vipps/invoice-2026-001",
              "format": "svg",
              "size": 1024,
              "margin": 4,
              "fgColor": "#111111",
              "bgColor": "#ffffff",
              "errorCorrectionLevel": "H"
            }
          },
          "qris": {
            "label": "QRIS supporting payment link",
            "bestFormats": [
              "svg",
              "png",
              "pdf"
            ],
            "request": {
              "value": "https://merchant.example.co.id/qris/invoice-2026-001",
              "format": "svg",
              "size": 1024,
              "margin": 4,
              "fgColor": "#111111",
              "bgColor": "#ffffff",
              "errorCorrectionLevel": "H"
            }
          },
          "paypal": {
            "label": "PayPal.Me payment link",
            "bestFormats": [
              "svg",
              "png",
              "pdf"
            ],
            "request": {
              "value": "https://paypal.me/qrcodecrafter/25USD",
              "format": "svg",
              "size": 1024,
              "margin": 4,
              "fgColor": "#111111",
              "bgColor": "#ffffff",
              "errorCorrectionLevel": "H"
            }
          },
          "venmo": {
            "label": "Venmo profile link",
            "bestFormats": [
              "svg",
              "png",
              "pdf"
            ],
            "request": {
              "value": "https://venmo.com/u/qrcodecrafter",
              "format": "svg",
              "size": 1024,
              "margin": 4,
              "fgColor": "#111111",
              "bgColor": "#ffffff",
              "errorCorrectionLevel": "H"
            }
          },
          "cashapp": {
            "label": "Cash App $Cashtag link",
            "bestFormats": [
              "svg",
              "png",
              "pdf"
            ],
            "request": {
              "value": "https://cash.app/$qrcodecrafter",
              "format": "svg",
              "size": 1024,
              "margin": 4,
              "fgColor": "#111111",
              "bgColor": "#ffffff",
              "errorCorrectionLevel": "H"
            }
          },
          "promptpay": {
            "label": "Thai PromptPay payment payload",
            "bestFormats": [
              "svg",
              "png",
              "pdf"
            ],
            "request": {
              "value": "00020101021229370016A000000677010111011300668123456785802TH53037645406125.5063047652",
              "format": "svg",
              "size": 1024,
              "margin": 4,
              "fgColor": "#111111",
              "bgColor": "#ffffff",
              "errorCorrectionLevel": "H"
            }
          },
          "vietqr": {
            "label": "Vietnam VietQR bank transfer payload",
            "bestFormats": [
              "svg",
              "png",
              "pdf"
            ],
            "request": {
              "value": "00020101021238560010A0000007270126000697041501121133666688880208QRIBFTTA530370454061500005802VN62100806INV123630421F5",
              "format": "svg",
              "size": 1024,
              "margin": 4,
              "fgColor": "#111111",
              "bgColor": "#ffffff",
              "errorCorrectionLevel": "H"
            }
          },
          "swissqr": {
            "label": "Swiss QR-bill structured-address payment payload",
            "bestFormats": [
              "pdf",
              "svg",
              "eps"
            ],
            "request": {
              "value": "SPC\n0200\n1\nCH9300762011623852957\nS\nRobert Schneider AG\nRue du Lac\n1268\n2501\nBiel\nCH\n\n\n\n\n\n\n\n199.95\nCHF\n\n\n\n\n\n\n\nNON\n\nInvoice 2026-001\nEPD\n\n\n",
              "format": "pdf",
              "size": 1024,
              "margin": 4,
              "fgColor": "#111111",
              "bgColor": "#ffffff",
              "errorCorrectionLevel": "H"
            }
          }
        },
        "properties": {
          "value": {
            "type": "string",
            "description": "Data encoded in the QR code",
            "maxLength": 2048
          },
          "format": {
            "type": "string",
            "description": "Output format for the QR code asset",
            "enum": [
              "svg",
              "png",
              "jpg",
              "webp",
              "pdf",
              "eps"
            ],
            "default": "png"
          },
          "size": {
            "type": "integer",
            "minimum": 256,
            "maximum": 4096,
            "default": 1024,
            "description": "Pixel width/height of the generated asset"
          },
          "margin": {
            "type": "integer",
            "minimum": 0,
            "maximum": 16,
            "default": 4,
            "description": "Quiet-zone margin around the QR code modules"
          },
          "fgColor": {
            "type": "string",
            "pattern": "^#?[0-9a-fA-F]{6}$",
            "description": "Hex foreground color, for example #000000"
          },
          "bgColor": {
            "type": "string",
            "pattern": "^#?[0-9a-fA-F]{6}$",
            "description": "Hex background color, for example #FFFFFF"
          },
          "errorCorrectionLevel": {
            "type": "string",
            "enum": [
              "L",
              "M",
              "Q",
              "H"
            ],
            "default": "H",
            "description": "QR error correction level"
          },
          "logo": {
            "type": "string",
            "nullable": true,
            "maxLength": 1500000,
            "pattern": "^data:image\\/(png|jpe?g|webp);base64,.+",
            "description": "Optional base64 data URL for a logo (PNG, JPG, or WEBP) to composite at the center. Files larger than 1MB are rejected."
          }
        }
      },
      "GenerateQrResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "string",
            "description": "Base64 encoded asset bytes"
          },
          "dataUrl": {
            "type": "string",
            "description": "Ready-to-embed data URL built from contentType and base64 data",
            "example": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
          },
          "downloadUrl": {
            "type": "string",
            "description": "Relative GET URL for retrieving the generated asset without embedding base64 bytes. Emitted only for no-logo public HTTP(S) URL payloads that do not include obvious credential-style query parameters.",
            "example": "/.netlify/functions/generate-qr?value=https%3A%2F%2Fexample.com&format=svg&size=1024"
          },
          "contentType": {
            "type": "string",
            "example": "image/png"
          },
          "extension": {
            "type": "string",
            "example": "png"
          },
          "suggestedFilename": {
            "type": "string",
            "example": "qrcode-example"
          },
          "byteLength": {
            "type": "integer",
            "description": "Exact number of decoded bytes in the base64 data field",
            "example": 5342
          },
          "dimensions": {
            "$ref": "#/components/schemas/GeneratedAssetDimensions"
          },
          "qrOptions": {
            "type": "object",
            "description": "Normalized QR options used to generate the asset",
            "properties": {
              "size": {
                "type": "integer",
                "example": 1024
              },
              "margin": {
                "type": "integer",
                "example": 4
              },
              "errorCorrectionLevel": {
                "type": "string",
                "enum": [
                  "L",
                  "M",
                  "Q",
                  "H"
                ],
                "example": "H"
              }
            }
          }
        }
      },
      "GenerateBulkQrRequest": {
        "type": "object",
        "required": [
          "rows"
        ],
        "properties": {
          "rows": {
            "description": "Up to 50 QR payload rows. Provide either a CSV string with headers such as filename,value or an array of row objects with value and optional filename fields.",
            "oneOf": [
              {
                "type": "string",
                "maxLength": 220000
              },
              {
                "type": "array",
                "minItems": 1,
                "maxItems": 50,
                "items": {
                  "$ref": "#/components/schemas/GenerateBulkQrRow"
                }
              }
            ]
          },
          "format": {
            "type": "string",
            "description": "Shared output format for every generated QR file in the ZIP",
            "enum": [
              "svg",
              "png",
              "jpg",
              "webp",
              "pdf",
              "eps"
            ],
            "default": "svg"
          },
          "size": {
            "type": "integer",
            "minimum": 256,
            "maximum": 4096,
            "default": 1024,
            "description": "Pixel width/height for SVG and raster assets, point size for EPS/PDF QR artwork"
          },
          "margin": {
            "type": "integer",
            "minimum": 0,
            "maximum": 16,
            "default": 4,
            "description": "Quiet-zone margin around every QR code"
          },
          "fgColor": {
            "type": "string",
            "pattern": "^#?[0-9a-fA-F]{6}$",
            "default": "#111111",
            "description": "Shared foreground color"
          },
          "bgColor": {
            "type": "string",
            "pattern": "^#?[0-9a-fA-F]{6}$",
            "default": "#ffffff",
            "description": "Shared background color"
          },
          "errorCorrectionLevel": {
            "type": "string",
            "enum": [
              "L",
              "M",
              "Q",
              "H"
            ],
            "default": "H",
            "description": "Shared QR error correction level"
          }
        },
        "x-agent-rate-limit": {
          "model": "cost-weighted per client",
          "maxRows": 50,
          "defaultBudgetUnits": 180,
          "authenticatedBudgetUnits": 600,
          "formatCosts": {
            "svg": 1,
            "png": 3,
            "jpg": 4,
            "webp": 4,
            "pdf": 6,
            "eps": 3
          },
          "guidance": "Prefer SVG for large batches, split PDF/WebP/JPG batches, and request application/zip when a direct ZIP download is preferred over base64 JSON."
        }
      },
      "GenerateBulkQrRow": {
        "type": "object",
        "required": [
          "value"
        ],
        "properties": {
          "value": {
            "type": "string",
            "maxLength": 2048,
            "description": "Exact QR payload to encode for this file"
          },
          "filename": {
            "type": "string",
            "maxLength": 64,
            "description": "Optional filename stem. Unsafe characters are replaced before ZIP creation."
          },
          "name": {
            "type": "string",
            "maxLength": 64,
            "description": "Alternative filename stem accepted for spreadsheet-style rows."
          },
          "label": {
            "type": "string",
            "maxLength": 64,
            "description": "Alternative filename stem accepted for spreadsheet-style rows."
          }
        }
      },
      "GenerateBulkQrResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "string",
            "description": "Base64 encoded ZIP archive containing QR files plus manifest.csv and manifest.json"
          },
          "dataUrl": {
            "type": "string",
            "description": "Ready-to-download ZIP data URL",
            "example": "data:application/zip;base64,UEsDB..."
          },
          "contentType": {
            "type": "string",
            "example": "application/zip"
          },
          "extension": {
            "type": "string",
            "example": "zip"
          },
          "suggestedFilename": {
            "type": "string",
            "example": "qrcodecrafter-bulk-svg.zip"
          },
          "byteLength": {
            "type": "integer",
            "description": "Exact ZIP byte length"
          },
          "fileCount": {
            "type": "integer",
            "description": "Number of generated QR files in the ZIP"
          },
          "failedCount": {
            "type": "integer",
            "description": "Number of rows recorded as failed in the manifest"
          },
          "manifest": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkQrManifestRow"
            }
          },
          "qrOptions": {
            "type": "object",
            "properties": {
              "format": {
                "type": "string",
                "enum": [
                  "svg",
                  "png",
                  "jpg",
                  "webp",
                  "pdf",
                  "eps"
                ]
              },
              "size": {
                "type": "integer"
              },
              "margin": {
                "type": "integer"
              },
              "fgColor": {
                "type": "string"
              },
              "bgColor": {
                "type": "string"
              },
              "errorCorrectionLevel": {
                "type": "string",
                "enum": [
                  "L",
                  "M",
                  "Q",
                  "H"
                ]
              }
            }
          }
        }
      },
      "BulkQrManifestRow": {
        "type": "object",
        "properties": {
          "filename": {
            "type": "string",
            "example": "homepage.svg"
          },
          "value": {
            "type": "string",
            "example": "https://example.com"
          },
          "format": {
            "type": "string",
            "enum": [
              "svg",
              "png",
              "jpg",
              "webp",
              "pdf",
              "eps"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "generated",
              "failed"
            ]
          },
          "bytes": {
            "type": "integer",
            "nullable": true
          },
          "message": {
            "type": "string"
          }
        }
      },
      "GeneratedAssetDimensions": {
        "type": "object",
        "description": "Rendered asset dimensions. Raster and SVG assets use pixels; PDF and EPS use points.",
        "required": [
          "width",
          "height",
          "unit"
        ],
        "properties": {
          "width": {
            "type": "number",
            "example": 1024
          },
          "height": {
            "type": "number",
            "example": 1024
          },
          "unit": {
            "type": "string",
            "enum": [
              "px",
              "pt"
            ],
            "example": "px"
          }
        }
      },
      "DynamicQrCreateRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "destination"
        ],
        "properties": {
          "destination": {
            "type": "string",
            "format": "uri",
            "pattern": "^https://",
            "maxLength": 2048,
            "description": "Public HTTPS destination. Private, local, reserved, and credential-bearing URLs are rejected."
          },
          "label": {
            "type": "string",
            "maxLength": 80
          }
        }
      },
      "DynamicQrUpdateRequest": {
        "type": "object",
        "additionalProperties": false,
        "minProperties": 1,
        "properties": {
          "destination": {
            "type": "string",
            "format": "uri",
            "pattern": "^https://",
            "maxLength": 2048
          },
          "label": {
            "type": "string",
            "maxLength": 80
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "paused"
            ]
          },
          "rotateToken": {
            "type": "boolean",
            "description": "Replace the bearer capability and return the new token once in the response."
          }
        }
      },
      "DynamicQrRecord": {
        "type": "object",
        "required": [
          "slug",
          "destination",
          "label",
          "status",
          "version",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "slug": {
            "type": "string",
            "pattern": "^[A-Za-z0-9_-]{22}$"
          },
          "destination": {
            "type": "string",
            "format": "uri"
          },
          "label": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "paused"
            ]
          },
          "version": {
            "type": "integer",
            "minimum": 1
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "DynamicQrCreateResponse": {
        "type": "object",
        "required": [
          "success",
          "record",
          "managementToken",
          "redirectUrl",
          "managementUrl"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "record": {
            "$ref": "#/components/schemas/DynamicQrRecord"
          },
          "managementToken": {
            "type": "string",
            "pattern": "^[A-Za-z0-9_-]{43}$",
            "description": "One-time bearer capability. It is never returned by later reads."
          },
          "redirectUrl": {
            "type": "string",
            "format": "uri"
          },
          "managementUrl": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "DynamicQrManageResponse": {
        "type": "object",
        "required": [
          "success",
          "record",
          "redirectUrl"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "record": {
            "$ref": "#/components/schemas/DynamicQrRecord"
          },
          "redirectUrl": {
            "type": "string",
            "format": "uri"
          },
          "analytics": {
            "$ref": "#/components/schemas/DynamicQrAnalyticsSummary"
          }
        }
      },
      "DynamicQrAnalyticsSummary": {
        "type": "object",
        "description": "Enabled on the production deployment. The analytics property remains optional so non-production or deliberately disabled deployments can omit it.",
        "required": [
          "available",
          "approximate",
          "retentionDays",
          "dailyCountLimit"
        ],
        "properties": {
          "available": {
            "type": "boolean",
            "description": "False when analytics are enabled but aggregate storage is temporarily unavailable."
          },
          "approximate": {
            "type": "boolean",
            "enum": [
              true
            ],
            "description": "Counts are best-effort redirects, not unique people or guaranteed scans."
          },
          "retentionDays": {
            "type": "integer",
            "enum": [
              90
            ]
          },
          "dailyCountLimit": {
            "type": "integer",
            "enum": [
              100000
            ],
            "description": "Maximum aggregate redirects counted for one slug in one UTC day. Later eligible redirects still work but are not counted."
          },
          "totalScans": {
            "type": "integer",
            "minimum": 0,
            "description": "Lifetime aggregate redirect count. Present when analytics storage is available."
          },
          "daily": {
            "type": "array",
            "maxItems": 90,
            "items": {
              "type": "object",
              "required": [
                "date",
                "count"
              ],
              "properties": {
                "date": {
                  "type": "string",
                  "format": "date"
                },
                "count": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 100000
                }
              }
            }
          },
          "lastCountedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "DynamicQrUpdateResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/DynamicQrManageResponse"
          },
          {
            "type": "object",
            "properties": {
              "managementToken": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{43}$",
                "description": "Present only when rotateToken is true; store it because it is not returned again."
              },
              "managementUrl": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        ]
      },
      "DynamicQrVaultCreateRequest": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 80
          }
        }
      },
      "DynamicQrVaultRenameRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 80
          }
        }
      },
      "DynamicQrVaultChildMetadata": {
        "type": "object",
        "properties": {
          "folder": {
            "type": "string",
            "maxLength": 40
          },
          "tags": {
            "type": "array",
            "maxItems": 8,
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 24
            }
          }
        }
      },
      "DynamicQrVaultChildCreateRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "destination"
        ],
        "properties": {
          "destination": {
            "type": "string",
            "format": "uri",
            "pattern": "^https://",
            "maxLength": 2048
          },
          "label": {
            "type": "string",
            "maxLength": 80
          },
          "folder": {
            "type": "string",
            "maxLength": 40
          },
          "tags": {
            "type": "array",
            "maxItems": 8,
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 24
            }
          }
        }
      },
      "DynamicQrVaultChildUpdateRequest": {
        "type": "object",
        "additionalProperties": false,
        "minProperties": 1,
        "properties": {
          "destination": {
            "type": "string",
            "format": "uri",
            "pattern": "^https://",
            "maxLength": 2048
          },
          "label": {
            "type": "string",
            "maxLength": 80
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "paused"
            ]
          },
          "folder": {
            "type": "string",
            "maxLength": 40
          },
          "tags": {
            "type": "array",
            "maxItems": 8,
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 24
            }
          }
        }
      },
      "DynamicQrVaultChildRecord": {
        "allOf": [
          {
            "$ref": "#/components/schemas/DynamicQrRecord"
          },
          {
            "$ref": "#/components/schemas/DynamicQrVaultChildMetadata"
          }
        ]
      },
      "DynamicQrVaultRecord": {
        "type": "object",
        "description": "Public authorized representation. Never contains managementTokenHash, qrSlugs, child credentials, or internal storage fields.",
        "required": [
          "vaultId",
          "name",
          "version",
          "createdAt",
          "updatedAt",
          "emptyExpiresAt",
          "records"
        ],
        "properties": {
          "vaultId": {
            "type": "string",
            "pattern": "^[A-Za-z0-9_-]{22}$"
          },
          "name": {
            "type": "string",
            "maxLength": 80
          },
          "version": {
            "type": "integer",
            "minimum": 1
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "emptyExpiresAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Empty projects expire after six hours. This is null once the project contains a QR code."
          },
          "records": {
            "type": "array",
            "maxItems": 50,
            "items": {
              "$ref": "#/components/schemas/DynamicQrVaultChildRecord"
            }
          }
        }
      },
      "DynamicQrVaultResponse": {
        "type": "object",
        "required": [
          "success",
          "vault"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "vault": {
            "$ref": "#/components/schemas/DynamicQrVaultRecord"
          }
        }
      },
      "DynamicQrVaultCreateResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/DynamicQrVaultResponse"
          },
          {
            "type": "object",
            "required": [
              "managementToken",
              "managementUrl"
            ],
            "properties": {
              "managementToken": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{43}$",
                "description": "One-time vault bearer capability, returned only on creation."
              },
              "managementUrl": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        ]
      },
      "DynamicQrVaultChildResponse": {
        "type": "object",
        "required": [
          "success",
          "record"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "record": {
            "$ref": "#/components/schemas/DynamicQrVaultChildRecord"
          }
        }
      },
      "DynamicQrVaultChildAnalyticsResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "success",
          "slug"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "slug": {
            "type": "string",
            "pattern": "^[A-Za-z0-9_-]{22}$"
          },
          "analytics": {
            "$ref": "#/components/schemas/DynamicQrAnalyticsSummary"
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "default": false
          },
          "error": {
            "type": "string"
          }
        }
      }
    },
    "parameters": {
      "DynamicQrVaultId": {
        "name": "vaultId",
        "in": "path",
        "required": true,
        "description": "22-character vault identifier; not sufficient for authorization",
        "schema": {
          "type": "string",
          "pattern": "^[A-Za-z0-9_-]{22}$"
        }
      },
      "DynamicQrSlug": {
        "name": "slug",
        "in": "path",
        "required": true,
        "description": "22-character dynamic QR identifier",
        "schema": {
          "type": "string",
          "pattern": "^[A-Za-z0-9_-]{22}$"
        }
      },
      "IfMatch": {
        "name": "If-Match",
        "in": "header",
        "required": true,
        "description": "Exact value returned by X-Dynamic-QR-Version, or the ETag when no intermediary has rewritten it",
        "schema": {
          "type": "string",
          "maxLength": 256
        }
      },
      "DynamicQrVersionMatch": {
        "name": "X-Dynamic-QR-Version",
        "in": "header",
        "required": false,
        "description": "Stable mirror of If-Match for intermediaries that rewrite or remove standard conditional headers",
        "schema": {
          "type": "string",
          "maxLength": 256
        }
      },
      "DynamicQrVaultVersionMatch": {
        "name": "X-Dynamic-QR-Vault-Version",
        "in": "header",
        "required": false,
        "description": "Stable mirror of the current vault ETag for intermediaries that rewrite conditional headers",
        "schema": {
          "type": "string",
          "maxLength": 256
        }
      }
    },
    "headers": {
      "ETag": {
        "description": "Opaque record version validator for conditional updates",
        "schema": {
          "type": "string"
        }
      },
      "DynamicQrVersion": {
        "description": "Stable record version validator mirrored separately because some development proxies rewrite ETag",
        "schema": {
          "type": "string"
        }
      },
      "DynamicQrVaultVersion": {
        "description": "Stable vault version validator. It is distinct from a nested child record validator.",
        "schema": {
          "type": "string"
        }
      }
    },
    "securitySchemes": {
      "AgentApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Agent-Api-Key",
        "description": "Optional API key used when integrations need scoped or rate-limited access."
      },
      "DynamicQrBearer": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "capability-token",
        "description": "Private 43-character management capability returned at creation or explicit token rotation."
      },
      "DynamicQrVaultBearer": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "capability-token",
        "description": "Private 43-character vault capability returned only when the vault is created. It authorizes the vault and all nested records; child credentials are never exposed."
      }
    }
  }
}
