{
  "id": "CMP-017",
  "slug": "cmp-017",
  "title": "Every mandatory campaign attribute must be explicitly set",
  "statement": "The mandatory campaign boolean attributes — embeddedLink, embeddedPhone, ageGated, directLending and numberPool — must each be explicitly true or false, never left unset.",
  "rationale": "An unset boolean is not the same as false: providers reject nulls on required attributes rather than defaulting them, because the declaration is the thing being relied on downstream. It is also the signature failure of a form filled by an integration that only sends changed fields, so the brand sees a rejection for a field they never knowingly left blank.",
  "layer": "CAMPAIGN",
  "layerSlug": "campaign",
  "object": "campaign attributes",
  "severity": "BLOCKING",
  "detectability": [
    "DETERMINISTIC"
  ],
  "failureClass": "RETRY_FIELD",
  "authorities": [
    "TCR",
    "Bandwidth",
    "AWS"
  ],
  "applicabilityText": "Applies to every 10DLC registration.",
  "universal": true,
  "remediation": "Set every attribute explicitly to true or false rather than leaving it unset — including the ones that are false. Done when your submission payload carries all five keys with boolean values, not when the form merely looks complete.",
  "example": "embeddedLink: false · embeddedPhone: false · ageGated: false · directLending: false · numberPool: false",
  "pitfalls": [
    "A PATCH-style integration that sends only changed fields will drop every attribute the user did not touch, which is why this fails most often on resubmission rather than first submission."
  ],
  "phase": "approval",
  "automated": true,
  "url": "https://ekas.io/rules/10dlc/campaign/cmp-017/",
  "markdown": "https://ekas.io/rules/10dlc/campaign/cmp-017.md",
  "registry": "https://ekas.io/rules/10dlc/",
  "updated": "2026-07-25",
  "licence": "CC BY 4.0 — https://creativecommons.org/licenses/by/4.0/"
}
