{
  "layer": "CROSS",
  "name": "Brand ↔ campaign",
  "url": "https://ekas.io/rules/10dlc/cross/",
  "updated": "2026-07-25",
  "licence": "CC BY 4.0 — https://creativecommons.org/licenses/by/4.0/",
  "count": 13,
  "rules": [
    {
      "id": "XBC-001",
      "slug": "xbc-001",
      "title": "Sole proprietor brands may only run the sole proprietor use case",
      "statement": "A SOLE_PROPRIETOR brand must register its campaign under the SOLE_PROPRIETOR use case; standard campaign types are unavailable to that tier.",
      "rationale": "The sole proprietor tier exists as a low-volume path for individuals with no EIN, and it comes with its own throughput caps and a single-number limit. Standard use cases assume a vetted registered entity behind them, so the platform refuses the combination rather than granting an individual standard-tier treatment.",
      "layer": "CROSS",
      "layerSlug": "cross",
      "object": "brand.entity_type + campaign.usecase",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "Twilio"
      ],
      "applicability": {
        "entityTypes": [
          "SOLE_PROPRIETOR"
        ]
      },
      "applicabilityText": "Applies when the brand is a sole proprietor.",
      "universal": false,
      "dependsOn": [
        "BRD-065"
      ],
      "remediation": "Select the Sole Proprietor use case for this campaign. If you need a standard use case such as Marketing, obtain an EIN and re-register the brand as a standard entity first — the tier, not the campaign, is what limits you.",
      "example": "Use case: SOLE_PROPRIETOR",
      "notes": "Catalog BRD-089. The most common failure after a sole proprietor brand is itself accepted.",
      "catalogIds": [
        "BRD-089"
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "XBC-002",
      "slug": "xbc-002",
      "title": "Charity use case requires a verified 501(c)(3) non-profit brand",
      "statement": "The CHARITY use case is restricted to a NON_PROFIT brand holding verified 501(c)(3) tax-exempt status.",
      "rationale": "Charitable messaging gets favourable treatment — better throughput and more tolerance for solicitation content — so eligibility is verified against the brand record rather than taken on trust. 501(c)(4), (5) and (6) organisations are tax-exempt but are NOT charities for this purpose, which is where most rejections come from.",
      "layer": "CROSS",
      "layerSlug": "cross",
      "object": "brand.entity_type + brand.tax_exempt_status + campaign.usecase",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "Twilio",
        "Infobip"
      ],
      "applicability": {
        "useCases": [
          "CHARITY"
        ]
      },
      "applicabilityText": "Applies when the use case is CHARITY.",
      "universal": false,
      "remediation": "Register the brand as NON_PROFIT with its 501(c)(3) EIN and declare the tax-exempt status on the brand record. The EIN must appear in the IRS Tax-Exempt Organization Search. If the organisation is a 501(c)(4) or (6), choose a different use case.",
      "example": "Entity type: NON_PROFIT · Tax exempt status: 501(c)(3) · Use case: CHARITY",
      "catalogIds": [
        "BRD-054",
        "BRD-056"
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "XBC-003",
      "slug": "xbc-003",
      "title": "Political use case requires a non-profit brand with political vetting",
      "statement": "The POLITICAL use case must sit on a NON_PROFIT brand carrying external political vetting recognised by both AT&T and T-Mobile.",
      "rationale": "Political messaging is the most scrutinised category on the network, and both major carriers require independent verification that the sender is who they claim to be before granting throughput. Vetting is imported into TCR from an external provider, so it cannot be satisfied by anything you type into the form.",
      "layer": "CROSS",
      "layerSlug": "cross",
      "object": "brand.entity_type + campaign.usecase",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "TCR",
        "AT&T",
        "T-Mobile"
      ],
      "applicability": {
        "useCases": [
          "POLITICAL"
        ]
      },
      "applicabilityText": "Applies when the use case is POLITICAL.",
      "universal": false,
      "remediation": "Register the brand as NON_PROFIT, then obtain political vetting (Campaign Verify or an equivalent both carriers accept) and import it into TCR before submitting the campaign. Do not order a political vet for a brand that already holds 501(c)(3/4/5/6) status — that combination is disallowed.",
      "notes": "Off-platform: only the entity type is checkable here. The vetting itself is bought from an external provider and imported into TCR, so the user must obtain it themselves and confirm the import landed before submitting — we can never return anything better than UNCLEAR on that half, and a PASS on entity type is not a prediction that the campaign will be approved.",
      "catalogIds": [
        "BRD-240",
        "OPS-166"
      ],
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Is political vetting already imported and visible on the brand, rather than ordered, in progress, or held only as a certificate you have not uploaded?",
        "howToCheck": [
          "Open the brand at your provider and confirm a political vet (Campaign Verify, or an equivalent both AT&T and T-Mobile accept) is listed against it.",
          "Confirm the brand's entity type is NON_PROFIT, and that it does not also hold 501(c)(3/4/5/6) status — that combination is disallowed."
        ],
        "failureLooksLike": "The certificate is sitting in an inbox rather than in TCR. Nothing on the campaign form says the vetting is missing, and the campaign is refused for a brand that looks complete."
      }
    },
    {
      "id": "XBC-004",
      "slug": "xbc-004",
      "title": "Emergency and public-safety use cases exclude sole proprietors",
      "statement": "Public-safety and emergency use cases are not available to a SOLE_PROPRIETOR brand.",
      "rationale": "Emergency messaging bypasses filtering that protects consumers from everything else, so it is restricted to registered entities that can be held accountable for misuse. An individual with no EIN cannot be vetted to that standard.",
      "layer": "CROSS",
      "layerSlug": "cross",
      "object": "brand.entity_type + campaign.usecase",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR"
      ],
      "applicability": {
        "entityTypes": [
          "SOLE_PROPRIETOR"
        ]
      },
      "applicabilityText": "Applies when the brand is a sole proprietor.",
      "universal": false,
      "remediation": "Register the organisation as a standard entity with its EIN. If the messaging is genuinely operational rather than emergency, choose CUSTOMER_CARE or ACCOUNT_NOTIFICATION instead.",
      "example": "Entity type: PRIVATE_PROFIT or GOVERNMENT · Use case: EMERGENCY",
      "catalogIds": [
        "BRD-159"
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "XBC-005",
      "slug": "xbc-005",
      "title": "Sole proprietor brand and campaign both require a reference ID",
      "statement": "referenceId is mandatory — not optional — on both the brand and the campaign for the sole proprietor tier.",
      "rationale": "The reference ID is how the sole proprietor tier ties a brand and campaign to the verified mobile number behind them, which is the only identity check that tier has. It is optional everywhere else, so integrations built against the standard flow omit it and fail here.",
      "layer": "CROSS",
      "layerSlug": "cross",
      "object": "brand.reference_id + campaign.reference_id",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR"
      ],
      "applicability": {
        "entityTypes": [
          "SOLE_PROPRIETOR"
        ]
      },
      "applicabilityText": "Applies when the brand is a sole proprietor.",
      "universal": false,
      "remediation": "Populate referenceId on both the brand and the campaign with your own stable identifier for this customer.",
      "example": "referenceId: acme-sp-2026-0041",
      "notes": "Catalog BRD-077 / CMP-022.",
      "catalogIds": [
        "CMP-022",
        "BRD-077"
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "XBC-006",
      "slug": "xbc-006",
      "title": "The brand must be verified before its campaign is submitted",
      "statement": "A campaign must not be submitted until the brand reaches an approved, verified identity status.",
      "rationale": "A campaign is judged against the brand as it stands the moment it arrives, so one submitted against an unverified brand is refused — and the refusal names the campaign. Teams then rewrite the description, the samples and the flow, none of which was the problem, and resubmit into the same wall. It happens because the brand call returns 200 with a pending status and looks like success.",
      "layer": "CROSS",
      "layerSlug": "cross",
      "object": "brand.identity_status + campaign submission",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "TCR",
        "AWS",
        "Twilio"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Hold the campaign until the brand identity status reads VERIFIED or VETTED_VERIFIED, and sequence the two submissions off the brand status event rather than off a timer. Done when the brand is in a final verified state at the moment the campaign is sent.",
      "notes": "The wait is at the registry and nothing here shortens it. What the user has to do is order the two submissions — brand first, campaign only once the status is final — because a campaign refused for this reason still consumes a submission and, at some providers, a fee. An UNVERIFIED status is not a brand defect on its own: it is the state a brand sits in while the check runs.",
      "catalogIds": [
        "OPS-312"
      ],
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Does the brand read VERIFIED or VETTED_VERIFIED at the moment the campaign is submitted, rather than PENDING?",
        "howToCheck": [
          "Fetch the brand immediately before submitting the campaign and read the identity status — do not rely on the 200 the create call returned, which succeeds while the status is still pending.",
          "Sequence the campaign off the brand status webhook rather than off a timer, so the campaign leaves only once the status is final."
        ],
        "failureLooksLike": "The campaign is refused and the error names the campaign, so the description, samples and flow are rewritten and resubmitted into the same wall — while the brand was the thing that was not ready."
      }
    },
    {
      "id": "XBC-007",
      "slug": "xbc-007",
      "title": "A public company must finish two-factor identity before any campaign",
      "statement": "A PUBLIC_PROFIT brand must complete its Authentication+ two-factor identity step before a campaign is created against it.",
      "rationale": "Publicly traded brands carry an extra identity step that no other entity type has, and it is the one gate that produces no error while it is outstanding: the brand verifies, looks healthy, and every campaign against it is refused. The two-factor mail goes to the business contact address, so it is routinely missed by the person doing the registration, who is rarely the person on that mailbox.",
      "layer": "CROSS",
      "layerSlug": "cross",
      "object": "brand.entity_type + brand.vetting + campaign submission",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "TCR"
      ],
      "applicability": {
        "entityTypes": [
          "PUBLIC_PROFIT"
        ]
      },
      "applicabilityText": "Applies when the brand is a public company.",
      "universal": false,
      "dependsOn": [
        "XBC-006"
      ],
      "remediation": "Order the Authentication+ vet explicitly after the identity check, watch the business contact mailbox for the two-factor mail, and hold the campaign until the vet is recorded on the brand. Done when the brand shows an Authentication+ vet before the campaign is submitted.",
      "notes": "The vet is an action at the registry, not a field on the submission, and the PIN arrives by mail on the registry's schedule. What the user has to do is confirm who receives the business contact mail and that they know to expect it — BRD-225 covers ordering the vet, BRD-226 the window it must be completed in; this rule is the campaign-side consequence of either being outstanding.",
      "catalogIds": [
        "OPS-311"
      ],
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Do you know who receives mail at the business contact address, and that they are expecting the Authentication+ two-factor message?",
        "howToCheck": [
          "Name the person on the business contact mailbox out loud. It is rarely the person doing the registration.",
          "Tell them the two-factor mail is coming and what to do with it, then confirm the completed vet appears on the brand before submitting the campaign."
        ],
        "failureLooksLike": "The brand verifies and looks healthy, every campaign against it is refused, and the two-factor mail is unopened in a shared inbox nobody watches."
      }
    },
    {
      "id": "XBC-008",
      "slug": "xbc-008",
      "title": "A sole proprietor gets one campaign and one number",
      "statement": "A SOLE_PROPRIETOR brand may hold exactly one campaign, and that campaign exactly one telephone number.",
      "rationale": "The sole proprietor tier is a low-volume path for individuals with no EIN, and the single-campaign, single-number limit is what the carriers accept in exchange for the reduced vetting. A second campaign is refused rather than queued, so somebody who registers a marketing campaign beside their appointment reminders loses the fee and the time. Pooling is the same limit stated the other way: there is only ever one number to pool.",
      "layer": "CROSS",
      "layerSlug": "cross",
      "object": "brand.entity_type + campaign count + campaign.number_pool",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "T-Mobile",
        "Twilio"
      ],
      "applicability": {
        "entityTypes": [
          "SOLE_PROPRIETOR"
        ]
      },
      "applicabilityText": "Applies when the brand is a sole proprietor.",
      "universal": false,
      "dependsOn": [
        "XBC-001"
      ],
      "remediation": "Fold everything the programme sends into the one sole-proprietor campaign, on one number, and turn number pooling off. If the business genuinely needs a second campaign or more throughput, obtain an EIN and re-register as a standard entity — the tier is the limit, not the campaign.",
      "example": "Sole proprietor: 1 campaign · 1 phone number · numberPool: false",
      "pitfalls": [
        "Registering the second campaign under a second sole-proprietor brand does not work either: the tier caps the mobile number behind the brands as well, so the same person cannot hold an unlimited number of them."
      ],
      "catalogIds": [
        "OPS-316"
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "XBC-010",
      "slug": "xbc-010",
      "title": "Every sample message must identify the registered brand",
      "statement": "Each sample must contain the registered brand name or DBA, matching the brand record rather than a marketing alias.",
      "rationale": "A consumer receiving a text from an unfamiliar number decides in about a second whether it is legitimate or spam, and the sender name is the only signal they have. Carriers therefore require the brand to identify itself in the message body, and Bandwidth checks every sample rather than just one.",
      "layer": "CROSS",
      "layerSlug": "cross",
      "object": "brand.display_name + campaign.sample[]",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Bandwidth",
        "TCR",
        "CTIA"
      ],
      "codes": [
        {
          "provider": "Bandwidth",
          "code": "8101",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Start every sample with the registered brand name followed by a colon. Use the name on the brand record — a marketing alias the reviewer cannot match to the registration reads as a mismatch.",
      "example": "Acme Coffee: your order #4471 is ready for pickup until 6pm. Reply STOP to opt out, HELP for help.",
      "pitfalls": [
        "Twilio accepts the name in at least one sample; Bandwidth requires it in all of them. We apply the stricter rule."
      ],
      "catalogIds": [
        "MSG-036",
        "MSG-037",
        "MSG-039"
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "XBC-011",
      "slug": "xbc-011",
      "title": "Opt-in description must carry the registered brand name",
      "statement": "The CTA / message-flow field must name the brand, matching the registered Brand or DBA.",
      "rationale": "The reviewer reads the message flow to confirm the consent a consumer gave was consent to hear from THIS brand. A flow describing an anonymous opt-in cannot establish that, and it is also the exact pattern a reseller registering someone else’s traffic would produce.",
      "layer": "CROSS",
      "layerSlug": "cross",
      "object": "brand.display_name + campaign.message_flow",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Bandwidth",
        "Telnyx",
        "AWS"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Name the brand explicitly in the opt-in description, and quote the consent wording the consumer agrees to — that wording should name the brand too.",
      "example": "Customers opt in at acmecoffee.com/signup by ticking an unchecked box agreeing to receive recurring automated marketing texts from Acme Coffee.",
      "catalogIds": [
        "CMP-070"
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "XBC-012",
      "slug": "xbc-012",
      "title": "HELP reply must identify the brand",
      "statement": "The HELP auto-reply must contain the registered brand name.",
      "rationale": "HELP exists so a recipient who does not recognise a number can find out who is texting them. A reply that omits the brand answers the wrong question and leaves reporting the message as spam as the consumer’s only remaining option.",
      "layer": "CROSS",
      "layerSlug": "cross",
      "object": "brand.display_name + campaign.help_message",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "Twilio",
        "CTIA"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Put the brand name at the start of the HELP reply and add a support contact a person can actually reach. CTIA expects contact information beyond the bare name.",
      "example": "Acme Coffee: for help, email support@acmecoffee.com or call 415-555-0134. Msg & data rates may apply. Reply STOP to unsubscribe.",
      "catalogIds": [
        "CMP-191"
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "XBC-013",
      "slug": "xbc-013",
      "title": "Brand, website and campaign content must describe the same business",
      "statement": "The registered brand name, the brand website, and what the campaign says it sends must be coherent.",
      "rationale": "Reviewers open the website and compare it against the campaign before approving anything. A mismatch — a pest-control site behind a campaign describing salon appointment reminders — is the classic signature of a reseller registering under a borrowed brand, so it is treated as an integrity failure rather than a copy problem.",
      "layer": "CROSS",
      "layerSlug": "cross",
      "object": "brand.company_name + brand.website + campaign.description",
      "severity": "BLOCKING",
      "detectability": [
        "AI_FORM"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Twilio",
        "TCR",
        "AWS",
        "Bandwidth"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30907",
          "remediable": true,
          "generation": "gen2"
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Make the campaign description describe the business the website actually presents, under the name the brand is registered with. If the website belongs to a parent or agency rather than the sender, register the brand that owns the customer relationship instead.",
      "example": "Website acmecoffee.com sells coffee subscriptions; description: \"Acme Coffee sends order updates and promotional offers to subscription customers who opted in at checkout.\"",
      "catalogIds": [
        "MSG-145"
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "XBC-014",
      "slug": "xbc-014",
      "title": "The description must name the registered business",
      "statement": "The campaign description must name the registered legal name or the registered DBA.",
      "rationale": "The description is where a reviewer decides which business they are vetting, and one that never names the registrant leaves them matching a programme against a brand record on trust. It is the same defect as a wrong name and reads worse: a description naming nobody offers nothing to reconcile, so there is no way to establish that this campaign belongs to this brand at all.",
      "layer": "CROSS",
      "layerSlug": "cross",
      "object": "brand.company_name + campaign.description",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Bandwidth",
        "Infobip",
        "AWS",
        "Sinch",
        "Plivo"
      ],
      "codes": [
        {
          "provider": "Bandwidth",
          "code": "2006",
          "remediable": true
        },
        {
          "provider": "Infobip",
          "code": "603",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Open the description with the registered name — the one on the brand record, not a product or campaign nickname — and keep it there. Done when the first sentence names the same business the brand record does.",
      "example": "Acme Coffee sends weekly promotional offers to customers who opted in at checkout — not \"We send weekly promotional offers to our customers\".",
      "pitfalls": [
        "A product or programme name is not the registered name: \"Acme Rewards\" does not match a brand registered as Acme Coffee Co, LLC unless Acme Rewards is the registered DBA."
      ],
      "notes": "The catalog grades this DETERMINISTIC + EXTERNAL_DATA because the strict form matches the description against the authoritative registry record. That lookup is not available here, so this rule settles the half that is: whether the description names the business the submission itself declares. A description agreeing with a brand record that is itself wrong is XBC-010 and CMP-037's territory.",
      "catalogIds": [
        "CMP-036"
      ],
      "phase": "approval",
      "automated": true
    }
  ]
}
