{
  "id": "CMP-103",
  "slug": "cmp-103",
  "title": "A QR flow must say where the code leads",
  "statement": "A QR opt-in must state whether the code opens a hosted opt-in form or a pre-filled SMS in the native messaging app.",
  "rationale": "Both destinations are permitted and they are graded by completely different rules — a hosted form owes a checkbox and a disclosure, a pre-filled SMS owes a confirmation reply and keyword handling — so a reviewer who cannot tell which one this is cannot begin. Submitters omit it because from their side there is only one obvious answer, and which one is obvious depends on who built the poster.",
  "layer": "CAMPAIGN",
  "layerSlug": "campaign",
  "object": "campaign.message_flow + QR destination",
  "severity": "BLOCKING",
  "detectability": [
    "AI_FORM"
  ],
  "failureClass": "RETRY_FIELD",
  "authorities": [
    "Twilio",
    "Klaviyo"
  ],
  "codes": [
    {
      "provider": "Twilio",
      "code": "30909",
      "remediable": true
    }
  ],
  "applicability": {
    "consentMethods": [
      "qr"
    ]
  },
  "applicabilityText": "Applies when consent was collected by QR code.",
  "universal": false,
  "remediation": "Say which of the two the code does, and give the destination: the opt-in URL, or the number and body of the pre-filled message. Done when the flow names the destination type in words rather than leaving it to be inferred from the URL.",
  "example": "Scanning the poster QR opens a pre-filled SMS to 55512 with the body JOIN; the customer presses send, which is the opt-in.",
  "notes": "Neither destination is preferred — the rule is about the flow saying which one, not about choosing between them. Whether a hosted destination is a specific opt-in page rather than the homepage is CMP-064, which reads the URL itself.",
  "phase": "approval",
  "automated": true,
  "url": "https://ekas.io/rules/10dlc/campaign/cmp-103/",
  "markdown": "https://ekas.io/rules/10dlc/campaign/cmp-103.md",
  "registry": "https://ekas.io/rules/10dlc/",
  "updated": "2026-07-25",
  "licence": "CC BY 4.0 — https://creativecommons.org/licenses/by/4.0/"
}
