---
title: "Generate and verify a QR code asset"
method: POST
path: "/.netlify/functions/generate-verified-qr"
---

# Generate and verify a QR code asset

`POST /.netlify/functions/generate-verified-qr`

Generate one SVG, PNG, JPG, or WebP asset, perform a structural payload review, assess quiet-zone, contrast, and error-correction settings, decode the final generated file with jsQR, compare payload SHA-256 hashes, and return a bounded evidence-linked receipt. Asset bytes are returned only when final-file decoding matches the requested payload. A decode failure returns HTTP 422 with the full receipt and no asset bytes. The receipt does not include the decoded payload. This is not print, device, ISO, accessibility, malware, or security certification.

## Request body

- GenerateVerifiedQrRequest
  - `value` string, required — Data encoded in the QR code
  - `format` 'svg' | 'png' | 'jpg' | 'webp' — Final output format. PDF and EPS are excluded because this workflow decodes the final generated asset.
  - `size` integer — Pixel width/height of the generated asset
  - `margin` integer — Quiet-zone margin around the QR code modules
  - `fgColor` string — Hex foreground color, for example #000000
  - `bgColor` string — Hex background color, for example #FFFFFF
  - `errorCorrectionLevel` 'L' | 'M' | 'Q' | 'H' — QR error correction level
  - `logo` string, nullable — Optional base64 data URL for a logo (PNG, JPG, or WEBP) to composite at the center. Files larger than 1MB are rejected.

## Response `200`

Generated asset whose final-file decode matched the requested payload, plus a bounded verification receipt

- GenerateVerifiedQrResponse
  - `success` boolean, required
  - `data` string — Base64 encoded asset bytes
  - `dataUrl` string — Ready-to-embed data URL built from contentType and base64 data
  - `downloadUrl` string — 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.
  - `contentType` string
  - `extension` string
  - `suggestedFilename` string
  - `byteLength` integer — Exact number of decoded bytes in the base64 data field
  - `dimensions` GeneratedAssetDimensions — Rendered asset dimensions. Raster and SVG assets use pixels; PDF and EPS use points.
    - `width` number, required
    - `height` number, required
    - `unit` 'px' | 'pt', required
  - `qrOptions` object — Normalized QR options used to generate the asset
    - `size` integer
    - `margin` integer
    - `errorCorrectionLevel` 'L' | 'M' | 'Q' | 'H'
  - `assetSha256` string, required — SHA-256 hash of the final generated asset bytes.
  - `verification` object, required
    - `version` '1.0', required
    - `status` 'verified' | 'verified_with_cautions', required
    - `productionReady` boolean, required — True only when the final asset decodes to the requested payload and every bounded workflow check passes without caution.
    - `verifiedAt` string, date-time, required
    - `payload` QrSafePayloadReview, required
      - `kind` 'url' | 'email' | 'phone' | 'sms' | 'wifi' | 'vcard' | 'event' | 'location' | 'payment' | 'text', required
      - `level` 'clear' | 'caution' | 'blocked', required
      - `displayHost` string, nullable, required
      - `protocol` 'http:' | 'https:', nullable, required
      - `warnings` string[], required — Namespaced structural warning codes. No decoded payload content is included.
    - `decode` object, required
      - `decoder` 'jsQR 1.4.0', required
      - `status` 'exact_match' | 'normalized_match' | 'not_detected' | 'mismatch', required
      - `requestedPayloadSha256` string, required
      - `decodedPayloadSha256` string, nullable
      - `payloadHashMatch` boolean, required
    - `productionChecks` QrProductionChecks, required
      - `quietZone` object, required
        - `margin` integer, required
        - `recommendedMinimum` 4, required
        - `passed` boolean, required
      - `contrast` object, required
        - `ratio` number, required
        - `workflowThreshold` 4.5, required
        - `foregroundDarker` boolean, required
        - `passed` boolean, required
      - `errorCorrection` object, required
        - `level` 'L' | 'M' | 'Q' | 'H', required
        - `logoPresent` boolean, required
        - `passed` boolean, required — Passes when no logo is present or a logo uses H error correction.
    - `cautions` string[], required
    - `evidence` object, required
      - `readabilityLab` string, uri, required
      - `methodology` string, uri, required
      - `release` string, uri, required
    - `limitation` string, required — Explicitly states that one software decoder and rendering pipeline do not provide print, device, ISO, accessibility, malware, or security certification.

## Other responses

- `400` — Invalid request or non-decodable output format
- `401` — Missing or invalid API key when key enforcement is enabled
- `422` — Payload blocked before generation, or final asset failed decode or payload comparison
- `429` — Cost budget or verification concurrency limit reached
- `500` — Generation or verification pipeline error

---

[API](https://skmtc.net/qrcodecrafter/apis/qrcodecrafter-api-2.md) · [All operations](https://skmtc.net/qrcodecrafter/apis/qrcodecrafter-api-2/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/qrcodecrafter/qrcodecrafter-api-2/revisions/87cd2664770b/schema)
