{
  "id": "CMP-176",
  "slug": "cmp-176",
  "title": "Declaring opt-in requires opt-in keywords where the provider pairs them",
  "statement": "Where the provider ties the two fields together, declaring subscriberOptin true requires optinKeywords to be populated.",
  "rationale": "The provider models opt-in as keyword-driven and validates the pair, so a web-form programme that has no keyword to give is rejected for a field it had no reason to fill in. The fix is not to invent a keyword but to declare the ones the programme already honours — START and its variants are answered by every platform whether or not anyone advertises them.",
  "layer": "CAMPAIGN",
  "layerSlug": "campaign",
  "object": "campaign.optin_keywords + campaign.subscriber_optin",
  "severity": "BLOCKING",
  "detectability": [
    "DETERMINISTIC"
  ],
  "failureClass": "RETRY_FIELD",
  "authorities": [
    "Bird"
  ],
  "applicabilityText": "Applies to every 10DLC registration.",
  "universal": true,
  "remediation": "Populate the opt-in keyword field with the keywords your platform actually answers — START and UNSTOP at minimum, plus any keyword your signage advertises. Done when the field is non-empty and every keyword in it triggers a subscription on your side.",
  "example": "subscriberOptin: true · optin_keywords: START, UNSTOP, JOIN",
  "notes": "Bird's campaign form makes optinKeywords conditionally mandatory on subscriberOptin. The condition is applied inside the check rather than as a `providers` tag, because a tag resolves YES on an unknown submission target and would then demand opt-in keywords from every web-form and checkout registration in the registry — TCR requires them only for keyword opt-in (CMP-096).",
  "phase": "approval",
  "automated": true,
  "url": "https://ekas.io/rules/10dlc/campaign/cmp-176/",
  "markdown": "https://ekas.io/rules/10dlc/campaign/cmp-176.md",
  "registry": "https://ekas.io/rules/10dlc/",
  "updated": "2026-07-25",
  "licence": "CC BY 4.0 — https://creativecommons.org/licenses/by/4.0/"
}
