{
  "layer": "BRAND",
  "name": "Brand",
  "url": "https://ekas.io/rules/10dlc/brand/",
  "updated": "2026-07-25",
  "licence": "CC BY 4.0 — https://creativecommons.org/licenses/by/4.0/",
  "count": 196,
  "rules": [
    {
      "id": "BRD-001",
      "slug": "brd-001",
      "title": "A legal company name is required for every entity but a sole proprietor",
      "statement": "The legal company name field must be populated for every entity type except sole proprietor, where TCR wants it omitted and the person's name used instead.",
      "rationale": "The legal name is what every downstream check keys on — the IRS match, the duplicate-brand check, the vetting report — so an empty one does not fail politely at the end, it makes the whole registration unverifiable. The sole-proprietor carve-out is the part that catches people: submitting a company name there is as wrong as omitting one anywhere else.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.company_name",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "AWS",
        "Bandwidth",
        "Twilio"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Enter the legal entity name exactly as it appears on the IRS CP-575 or 147C letter. For a sole proprietor, leave this field empty and populate the first and last name fields instead. Done when the name here matches the tax record character for character.",
      "example": "company_name: Acme Coffee Co, LLC",
      "pitfalls": [
        "A sole proprietor who types their trading name here is routed into the wrong verification path and fails an identity check that was never meant to run."
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-002",
      "slug": "brd-002",
      "title": "Legal name must match the IRS record for the EIN",
      "statement": "The registered legal company name must match the IRS CP-575 / 147C record for the submitted EIN, character for character.",
      "rationale": "Vetting queries IRS records directly, so the legal name is matched mechanically rather than judged. Punctuation and capitalisation differences that a human would ignore — \"ACME, Inc.\" against \"Acme Inc\" — fail the comparison, which is why this rejects registrations that look obviously correct to their owner.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.company_name + brand.ein",
      "severity": "BLOCKING",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "TCR",
        "Twilio",
        "Telnyx",
        "Bandwidth",
        "AWS"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30900",
          "remediable": true
        },
        {
          "provider": "AWS",
          "code": "BRAND_TAX_ID_MISMATCH",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Use the exact legal name printed on your IRS CP-575 confirmation letter (or request a 147C letter from the IRS). Punctuation and capitalisation matter: \"ACME, Inc.\" and \"Acme Inc\" are different records.",
      "notes": "We cannot verify this without an IRS lookup, so we surface it as a pre-submission warning with the evidence the user should check, never as a pass.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Does the legal name on the brand match the IRS CP-575 or 147C letter character for character, punctuation included?",
        "howToCheck": [
          "Open the CP-575 the IRS issued when the EIN was assigned. If it has been lost, call the IRS Business & Specialty Tax Line on 800-829-4933 and request a 147C — it is free and it is the same authoritative name.",
          "Read the name off the letter and compare it to the brand field one character at a time: commas, full stops, a leading \"The\", and the entity suffix all count."
        ],
        "failureLooksLike": "\"ACME, Inc.\" on the letter and \"Acme Inc\" in the form. A person reads those as the same company; the comparison is mechanical and reads them as two different records."
      }
    },
    {
      "id": "BRD-003",
      "slug": "brd-003",
      "title": "Legal name must carry its exact entity suffix as filed",
      "statement": "The registered legal name must include the entity suffix exactly as filed — no abbreviation, expansion, or omission.",
      "rationale": "Vetting matches your legal name against the IRS record as a string, so \"Acme Coffee Company\" does not match \"Acme Coffee Co\" and neither matches \"Acme Coffee\". Businesses reliably enter the name they use day to day rather than the one on their formation documents, and the resulting mismatch reads as a failed identity check rather than a typo.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.company_name",
      "severity": "BLOCKING",
      "detectability": [
        "AI_FORM"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "Twilio",
        "Telnyx",
        "Bandwidth"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Copy the legal name character for character from your IRS CP-575 letter or formation documents, including the suffix and its punctuation. Put the everyday name in the brand display name field instead.",
      "example": "Legal name: \"Acme Coffee Co, LLC\" · Display name: \"Acme Coffee\"",
      "pitfalls": [
        "Dropping the comma before LLC, or writing \"Incorporated\" where the filing says \"Inc.\", are both real mismatches."
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-006",
      "slug": "brd-006",
      "title": "Submit every name line above the address on a multi-line IRS record",
      "statement": "Where the IRS CP-575 or 147C prints the entity name across more than one line, every line above the address line belongs in the legal name, and nothing below it.",
      "rationale": "The IRS wraps long entity names onto a second line, and a business reading its own letter sees the first line as \"the name\" and the rest as an artefact of the page. Vetting compares the full registered string, so dropping the continuation is a name mismatch — and it is the hardest kind to spot, because the value in the field is visibly the company.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.company_name",
      "severity": "HIGH",
      "detectability": [
        "AI_FORM"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Twilio"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Open the CP-575 or 147C and read down to the address block. Concatenate every name line above it, in order, separated by a single space, into the legal name field. Done when the field holds the whole name as printed and stops at the line before the street address.",
      "example": "company_name: Acme Coffee Co, LLC — including the \"& Roasting Company\" continuation line, if the letter carries one",
      "pitfalls": [
        "The line below the name is the \"C/O\" or care-of line on many letters, and it looks like part of the name. It is not — including it fails the match as surely as omitting the continuation does."
      ],
      "notes": "In DIRECT CONFLICT with BRD-007, which is TCR's CSP User Guide instruction to submit only the first line. The catalog keeps both deliberately: the correct answer depends on the submission target, and neither is safe to apply universally. Where the destination is unknown, submit the full name and be ready to shorten it — Twilio, the stricter of the two, is also the more common target.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-007",
      "slug": "brd-007",
      "title": "TCR takes only the first line of the IRS-registered name",
      "statement": "On a submission that goes to TCR directly, the company name is the first line of the IRS-registered name and nothing after it.",
      "rationale": "TCR's CSP User Guide asks for the first line where Twilio asks for all of them, so the same IRS letter yields two different correct answers depending on where the registration is filed. A team that standardised on one form and then changed provider gets a name mismatch on a value that was right last month, which is a genuinely baffling rejection.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.company_name",
      "severity": "HIGH",
      "detectability": [
        "AI_FORM"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "For a direct TCR submission, take the first line of the IRS-registered name only. Done when the field matches line one of the letter exactly, with no continuation appended.",
      "example": "company_name: Acme Coffee Co, LLC — the first line, where the letter continues \"& Roasting Company\" on line two",
      "notes": "Conditional on the submission target, and NOT tagged with `providers` because TCR is the registry every route ends at rather than a provider we can select. The condition lives in the criteria instead, which open with a PASS boundary. In direct conflict with BRD-006 (Twilio); the catalog says explicitly not to merge them, because the two predicates disagree on the same input.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-008",
      "slug": "brd-008",
      "title": "Legal name must not carry an appended personal name or role",
      "statement": "The legal name field must contain only the entity name — not a contact person or role suffix appended to it.",
      "rationale": "Registration forms elsewhere often combine entity and contact, so people paste strings like \"ACME LLC Theresa Lopez - MBR\" into the legal name. That never matches the IRS record, and because the entity name is present inside the string it looks correct at a glance.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.company_name",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "Twilio"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Remove everything after the entity suffix. The contact person belongs in the brand contact fields, not in the legal name.",
      "example": "Legal name: \"Acme Coffee Co, LLC\" — not \"Acme Coffee Co, LLC Jane Doe - MBR\"",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-009",
      "slug": "brd-009",
      "title": "The legal name field takes the legal name, not the trading name",
      "statement": "A DBA, trade name, subsidiary name, or product name must not be submitted in the legal company name field.",
      "rationale": "Almost every business has two names and only one of them is on the tax record. The trading name is the one on the sign, the invoices, the website and in everyone's head, so it is the one that gets typed — and it fails the IRS match, which returns as \"we could not verify this business\" rather than as \"wrong name\". Product names are the same trap one level down: the messaging programme is for a product, so the product name feels like the subject of the registration.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.company_name vs brand.dba",
      "severity": "BLOCKING",
      "detectability": [
        "AI_FORM",
        "EXTERNAL_DATA"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Twilio",
        "AWS",
        "Plivo",
        "TCR"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30918",
          "remediable": true
        },
        {
          "provider": "Twilio",
          "code": "30914",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Move the trading name into the DBA field and put the name from the IRS letter in the legal name field. Both fields are submitted, so nothing is lost — the trading name is what reviewers compare against the website, and the legal name is what the tax match runs on. Done when the two fields hold different values and each is in the right box.",
      "example": "company_name: Acme Coffee Co, LLC · dba: Acme Coffee — not \"Acme Coffee\" in both",
      "pitfalls": [
        "A subsidiary registering under the parent's name fails the same way in reverse: the EIN belongs to the subsidiary, so the parent name matches nothing."
      ],
      "notes": "Confirming which name is on the tax record needs the IRS file, so the judged half only catches the recognisable shapes — a suffix-less legal name, or a product name in the entity field. The user has to confirm against their CP-575 that the value they submitted is the issued name.",
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Is the value in the legal name field the name printed on the IRS letter, rather than the trading name, a subsidiary name, or the product the messages are about?",
        "howToCheck": [
          "Put the two names side by side: the one on the CP-575, and the one on the sign, the invoices and the website.",
          "The IRS name goes in the legal name field; the trading name goes in the DBA field. Both are submitted, so nothing is lost."
        ],
        "failureLooksLike": "\"Acme Coffee\" in the legal name field and nothing in the DBA field. The tax match returns \"we could not verify this business\" rather than \"wrong name\", so the EIN gets checked repeatedly instead."
      }
    },
    {
      "id": "BRD-010",
      "slug": "brd-010",
      "title": "Take the legal name from the CP-575 or 147C, never a W-2 or W-9",
      "statement": "The legal name must come from the IRS CP-575 confirmation letter or a 147C letter — the name on a W-2 or W-9 is not authoritative for this purpose.",
      "rationale": "A W-9 is the document a business has to hand and fills in itself, so the name on it is whatever someone typed; the CP-575 is what the IRS actually issued. They differ more often than people expect — abbreviations, a dropped \"The\", a payroll-system truncation — and vetting matches against the issued record. The business is not being careless here; it is using the tax document it was asked for last time.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.company_name",
      "severity": "HIGH",
      "detectability": [
        "HUMAN"
      ],
      "failureClass": "TERMINAL_EVIDENCE",
      "authorities": [
        "Twilio",
        "HighLevel"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Find the CP-575 issued when the EIN was assigned and copy the name from it. If it has been lost, call the IRS Business & Specialty Tax Line and request a 147C letter — it is free, and it is the same authoritative name. Done when the field matches the letter, not the W-9.",
      "example": "company_name: Acme Coffee Co, LLC — as printed on the CP-575, not as typed on last year's W-9",
      "notes": "Off-platform: we cannot see which document the name came from. Surfaced as the question the user has to answer themselves — \"which piece of paper is this name on?\" — before submitting, because it is far cheaper to check now than after a failed vet. A 147C request takes one phone call and the IRS will read the name back.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Which piece of paper did this legal name come from — a CP-575 or 147C, or a W-2 or W-9?",
        "howToCheck": [
          "Ask whoever supplied the name which document they read it off.",
          "If the answer is a W-9, a W-2, an invoice or a bank record, go back to the CP-575 — the W-9 is a form the business filled in itself, so the name on it is whatever someone typed.",
          "No CP-575 on file: request a 147C from the IRS, which reads the issued name back to you."
        ],
        "failureLooksLike": "The name on the W-9 has been shortened by a payroll system or lost a leading \"The\", the business has used it for years, and vetting matches against the issued record instead."
      }
    },
    {
      "id": "BRD-011",
      "slug": "brd-011",
      "title": "A legal business name may back only one brand across the whole registry",
      "statement": "A legal business name already registered as a brand at TCR cannot be registered again, by anyone.",
      "rationale": "Brand uniqueness is registry-wide, not per account: if another CSP has already registered this business, the second submission collides with a record neither you nor the customer can see. Agencies hit this constantly when a client registered themselves first, or moved between platforms and left the old brand behind, and the rejection names a duplicate the customer will swear does not exist.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.company_name",
      "severity": "BLOCKING",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Twilio",
        "TCR"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30703",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Ask the customer whether they have ever registered 10DLC before, with anyone — including a previous agency or a platform they no longer use. If they have, the existing brand must be released or shared rather than duplicated; contact the CSP that holds it. Done when either no prior brand exists or the existing one has been transferred to you.",
      "notes": "Off-platform: the duplicate lives in TCR, which we cannot query. The user has to establish for themselves whether the business has an existing brand — the reliable way is to ask the customer directly who has previously sent SMS on their behalf, since a forgotten registration from a former vendor is the usual cause. Do not resubmit hoping for a different answer; the check is exact and repeatable.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Has this business ever registered a 10DLC brand before, with anyone — including a former agency or a platform it no longer uses?",
        "howToCheck": [
          "Ask the customer directly who has sent SMS on their behalf in the past, not whether they have a brand. A forgotten registration from a previous vendor is the usual cause.",
          "Where a prior brand exists, contact the CSP holding it to release or share it rather than registering a second one."
        ],
        "failureLooksLike": "The submission is refused as a duplicate of a brand the customer will swear does not exist, because it was created by an agency they parted with two years ago and it is invisible to both of you."
      }
    },
    {
      "id": "BRD-012",
      "slug": "brd-012",
      "title": "Name fields must read as natural business text",
      "statement": "The display name, company name, and any first and last name fields must contain real, natural text — not obfuscated, garbled, or placeholder strings.",
      "rationale": "Obfuscated names are how bad actors evade brand-level blocklists, so the check exists to catch deliberate garbling — but it also catches honest submissions, because an internal reference like \"ACME-STORE-04\" or a keyboard-mashed test value left in place looks identical to evasion from the outside. The reviewer cannot tell the difference and does not try.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.display_name + brand.company_name + brand.first_name + brand.last_name",
      "severity": "BLOCKING",
      "detectability": [
        "AI_FORM"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "Twilio",
        "Vonage"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30756",
          "remediable": true
        },
        {
          "provider": "TCR",
          "code": "556",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Replace the value with the name a customer would recognise, written the way it appears on the shopfront or the website. Internal identifiers, store codes and account numbers belong in the reference id field. Done when every name field reads as something you could say aloud to a customer.",
      "example": "display_name: Acme Coffee — not \"ACME-STORE-04\", \"acme test\", or \"Xx_acme_xX\"",
      "pitfalls": [
        "A test brand created during an integration and then promoted to production carries the test name with it, and nothing in the promotion path re-reads that field."
      ],
      "notes": "TCR enforces the obfuscation check explicitly on sole-proprietor brands, where the first and last name fields are the identity; Twilio 30756 applies it to every brand. Authored universally, per the strict-superset model.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-013",
      "slug": "brd-013",
      "title": "A brand must be a business, not a person",
      "statement": "Outside the sole-proprietor tier, the registered brand must be a business entity rather than an individual's personal identity.",
      "rationale": "A2P messaging is registered to businesses because the whole accountability chain — the tax record, the vetting report, the complaint route — hangs off a business existing. An individual registering under their own name outside the sole-proprietor tier has no such record, so nothing can be verified and the brand is refused. It happens honestly: consultants, coaches and creators genuinely trade as themselves, and the standard tier is the one the form defaults to.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.company_name + brand.entity_type",
      "severity": "BLOCKING",
      "detectability": [
        "AI_FORM"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Twilio"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30928",
          "remediable": true
        }
      ],
      "applicability": {
        "excludeEntityTypes": [
          "SOLE_PROPRIETOR"
        ]
      },
      "applicabilityText": "Applies when the brand is NOT a sole proprietor.",
      "universal": false,
      "remediation": "If the business is a registered entity, use its registered name and EIN. If it genuinely is you trading as yourself, switch to the sole-proprietor tier, which verifies by mobile OTP instead of by tax record and expects exactly a personal name. Done when the entity type and the name agree about what is being registered.",
      "example": "company_name: Acme Coffee Co, LLC on the standard tier — or \"Jane Doe\" on the sole-proprietor tier, never a person's name on the standard one",
      "pitfalls": [
        "Adding \"Consulting\" to your own name does not create an entity. If there is no registration behind the words, the standard tier still has nothing to verify."
      ],
      "notes": "The inverse of BRD-068, which requires a personal name on the sole-proprietor tier. The two are tagged to opposite sides of the same dimension so exactly one fires per registration.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-014",
      "slug": "brd-014",
      "title": "An acquired business registers the details it filed taxes under",
      "statement": "Where the business has been acquired, the brand must carry the company information used for tax reporting at the time — not the acquirer's.",
      "rationale": "After an acquisition the operating business keeps trading under its own name while its paperwork moves to the parent, and whoever fills in the registration reaches for the current org chart. Vetting looks up the EIN that actually filed, so the parent's name against the subsidiary's EIN — or the reverse — verifies as a mismatch. It is one of the few brand failures where both names are genuinely the company.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.company_name + brand.ein",
      "severity": "HIGH",
      "detectability": [
        "HUMAN"
      ],
      "failureClass": "TERMINAL_EVIDENCE",
      "authorities": [
        "HighLevel"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Establish which entity filed the most recent federal return for this business and register that name and that EIN together. If the acquisition consolidated the tax filing under the parent, register the parent; if the subsidiary still files separately, register the subsidiary. Done when the name and the EIN come from the same return.",
      "example": "company_name: Acme Coffee Co, LLC with EIN 12-3456789 — the entity that filed, even where the parent now owns it",
      "notes": "Off-platform: nothing on the form says an acquisition happened. The user has to answer this themselves by asking their finance team which entity filed the last federal return, and then take BOTH the name and the EIN from that return rather than mixing one from each side of the deal.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Which entity filed the most recent federal tax return for this business — and are the name and the EIN on this brand both taken from that return?",
        "howToCheck": [
          "Ask the finance team, not the org chart: after an acquisition the operating business keeps trading under its own name while the filing may have moved to the parent.",
          "Take the legal name and the EIN from the same return. Never one from each side of the deal."
        ],
        "failureLooksLike": "The parent's name against the subsidiary's EIN. Both are genuinely the company, and the lookup returns a mismatch that reads like a typo."
      }
    },
    {
      "id": "BRD-015",
      "slug": "brd-015",
      "title": "A brand covers exactly one sender",
      "statement": "Each brand must be scoped to a single message sender — one brand per company, client, franchise or subsidiary, and no number shared between brands.",
      "rationale": "The brand is what a consumer would use to work out who texted them, so a brand covering several companies makes that question unanswerable and puts each company's complaint history on the others' record. Franchise groups and agencies reach it by economy: one registration is cheaper than forty, and the Agents & Franchises use case sounds like permission to do exactly that. It is not — it describes messaging on behalf of franchisees, not registering them as one brand.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the brand record",
      "severity": "BLOCKING",
      "detectability": [
        "AI_FORM"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Twilio",
        "Bandwidth",
        "Telnyx"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30926",
          "remediable": true
        },
        {
          "provider": "Telnyx",
          "code": "710",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Register one brand per legal entity that sends, each with its own EIN, website and contact details, and give each brand its own numbers. Where you manage many of them, that relationship belongs on the CSP record rather than being folded into a single brand. Done when every company named anywhere in the campaign has its own brand.",
      "example": "One brand for Acme Coffee Co, LLC and a separate brand for each franchisee — not one \"Acme Coffee Group\" brand covering all of them",
      "pitfalls": [
        "Sharing one phone number across brands fails for the same reason from the other direction: the number is what the carrier attributes traffic by, so two brands on one number cannot be told apart."
      ],
      "notes": "Absorbs BRD-162 (one brand per end customer, stated as the ISV-side obligation) and OPS-367 (no number shared across brands). Distinct from BRD-160, which asks whether the RIGHT entity was registered; this rule asks whether ONE entity was.",
      "catalogIds": [
        "BRD-162",
        "OPS-367"
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-017",
      "slug": "brd-017",
      "title": "A tax ID is required for every entity but a sole proprietor",
      "statement": "A tax ID or business registration number must be supplied for every entity type except sole proprietor.",
      "rationale": "The tax ID is the identifier the brand is actually verified against, so without it there is nothing to check the name and address into — the registration cannot be approved, only held. Sole proprietors are the deliberate exception because they are verified by mobile OTP instead, which is the whole point of that tier.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.ein",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "AWS",
        "Bandwidth"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Enter the nine-digit EIN from your CP-575 or 147C letter. Non-US entities supply the registration number their home country issues. Done when the identifier is present and matches the document it came from.",
      "example": "ein: 12-3456789",
      "pitfalls": [
        "A brand-new EIN can be present and still fail verification because the IRS has not published it yet — that is BRD-027, and the fix is to wait rather than to change the number."
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-019",
      "slug": "brd-019",
      "title": "EIN must be nine digits",
      "statement": "The EIN must be exactly nine digits (formatting characters aside).",
      "rationale": "The EIN is the key the whole brand verification hangs on: it is what links your registration to a real, IRS-recognised entity. A malformed one cannot be looked up at all, so the registration fails before any judgement about your business is made.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.ein",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "Twilio",
        "Telnyx"
      ],
      "applicability": {
        "excludeEntityTypes": [
          "SOLE_PROPRIETOR"
        ]
      },
      "applicabilityText": "Applies when the brand is NOT a sole proprietor.",
      "universal": false,
      "remediation": "Enter the nine-digit EIN from your IRS documentation, e.g. 12-3456789.",
      "example": "EIN: 12-3456789",
      "catalogIds": [
        "BRD-018"
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-020",
      "slug": "brd-020",
      "title": "Submit the US EIN hyphenated",
      "statement": "A US EIN must be submitted in the hyphenated XX-XXXXXXX form.",
      "rationale": "Several providers match the EIN as a string rather than as a number, so an unhyphenated one misses a record that is sitting right there — and the rejection says the business could not be verified, which sends people off to check their address and their name. The hyphen is free to add and every provider that does not require it accepts it anyway.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.ein",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Twilio",
        "Telnyx",
        "Sinch"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Reformat the EIN as two digits, a hyphen, then seven digits. Done when the value reads 12-3456789 rather than 123456789.",
      "example": "ein: 12-3456789",
      "notes": "Three providers require the hyphen and the rest accept it, so this is authored universally rather than provider-tagged: the strict-superset form costs nothing and a tag here would silently drop the requirement for the providers that do enforce it. Distinct from BRD-019, which checks there are nine digits at all — the catalog says explicitly not to merge them.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-021",
      "slug": "brd-021",
      "title": "An SSN is not a business registration number",
      "statement": "A Social Security Number must not be submitted in the business registration number field.",
      "rationale": "A sole proprietor with no EIN reaches for the number they do have, and the field accepts nine digits without complaint. It fails verification — an SSN is not in any business register — and in the meantime a government identifier has been sent to a registry that had no business receiving it. The correct route for that user is the sole-proprietor tier, which asks for no tax ID at all.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.ein",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "AWS"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Remove the SSN. If the business has an EIN, use it; if it does not, register on the sole-proprietor tier, which verifies by mobile OTP instead. Done when the field holds an EIN or is empty on a sole-proprietor brand.",
      "example": "ein: 12-3456789 (an EIN) — never 123-45-6789 (an SSN)",
      "pitfalls": [
        "Applying for an EIN is free and takes minutes on the IRS site, so the sole-proprietor tier is a choice rather than the only option — but it is the right one below the volume threshold."
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-022",
      "slug": "brd-022",
      "title": "A DUNS number is not a US business registration number",
      "statement": "A DUNS number must not be submitted as the US business registration number.",
      "rationale": "DUNS is a commercial identifier issued by a credit bureau, and the registry checks against tax records — so a DUNS number is nine digits that match nothing. It reaches the field honestly, because procurement and vendor-onboarding systems ask for DUNS constantly and it feels like the same class of thing.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.ein",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "AWS"
      ],
      "applicability": {
        "excludeEntityTypes": [
          "SOLE_PROPRIETOR"
        ]
      },
      "applicabilityText": "Applies when the brand is NOT a sole proprietor.",
      "universal": false,
      "remediation": "Replace it with the EIN from your IRS letter. Keep the DUNS number for the systems that want it — it is simply not what this field verifies against. Done when the value is the nine-digit EIN in hyphenated form.",
      "example": "ein: 12-3456789 — the IRS EIN, not the nine-digit D-U-N-S",
      "notes": "Only the shape is checkable here: an unhyphenated nine-digit US identifier is the DUNS signature, since a real EIN should carry the hyphen (BRD-020). Confirming a value IS a DUNS number needs the D&B register, which is EXTERNAL_DATA and out of reach pre-submission.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-023",
      "slug": "brd-023",
      "title": "The identifier type must be one of the supported values",
      "statement": "Where a business-registration identifier type is declared, it must be one of EIN, DUNS, CBN, CN, ACN, CIN, VAT, VATRN, RN or Other.",
      "rationale": "The type tells the registry which register to look the number up in, so an unrecognised value does not degrade to a best guess — the lookup never runs and the brand stays unverified. Integrations produce this by passing through whatever their own CRM calls the field, and the value looks perfectly reasonable right up to the point where nothing happens.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.business_registration_identifier",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Twilio"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30701",
          "remediable": true
        },
        {
          "provider": "Twilio",
          "code": "30799",
          "remediable": true
        }
      ],
      "applicability": {
        "excludeEntityTypes": [
          "SOLE_PROPRIETOR"
        ]
      },
      "applicabilityText": "Applies when the brand is NOT a sole proprietor.",
      "universal": false,
      "remediation": "Set the identifier type to the code for the document the number came from: EIN for a US employer identification number, CBN for a Canadian business number, VAT or VATRN for a European VAT registration, and Other only when none of them fits. Done when the value is one of the ten codes, in upper case.",
      "example": "business_registration_identifier: EIN · ein: 12-3456789",
      "pitfalls": [
        "\"TAX_ID\", \"FEIN\" and \"Federal Tax ID\" all mean EIN and are all rejected — the enum takes the short code, not the name people use."
      ],
      "notes": "A US EIN passes without an explicit type because the value is unambiguous and TCR infers it, so the check only reports a value that is present and outside the enum. Declaring it anyway is worth doing: the Twilio Trust Hub API takes the field directly and rejects the submission when it is missing.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-024",
      "slug": "brd-024",
      "title": "The identifier value must match the type declared for it",
      "statement": "The business-registration identifier value must be in the form its declared type requires.",
      "rationale": "Declaring EIN and supplying a Canadian business number — or the reverse — sends a well-formed number to the wrong register, and the answer comes back as \"business not found\" rather than as a type error. It is a common integration defect precisely because both values are nine digits and both fields validate.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.business_registration_identifier + brand.ein",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "AWS",
        "Bandwidth"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Check the two fields against each other: the type names the document, the value is the number printed on it. If they disagree, correct whichever one is wrong rather than changing both. Done when the number is the one the named register issued.",
      "example": "business_registration_identifier: EIN · ein: 12-3456789 — nine digits, because that is what an EIN is",
      "notes": "Distinct from BRD-019, which asks only whether a US EIN has nine digits. This rule asks whether the value fits the type that was DECLARED for it, which is a different failure and produces a different fix. A type outside the enum is BRD-023 and is left to it.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-025",
      "slug": "brd-025",
      "title": "The issuing country must be declared, and must match the country of registration",
      "statement": "einIssuingCountry must be a valid ISO-3166 alpha-2 code and must equal the country the business is registered in.",
      "rationale": "TCR defaults this field to US when it is left unset, so a foreign brand that omits it is silently looked up in the US registers and fails as an unverifiable business rather than as a missing field. The default is the trap: the registration looks complete, and the one field that would have routed it correctly is the one nobody filled in.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.ein_issuing_country + brand.country",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "AWS",
        "Klaviyo"
      ],
      "codes": [
        {
          "provider": "TCR",
          "code": "501",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Set einIssuingCountry to the two-letter code of the country that issued the identifier, and make sure the brand country matches it. Done when both fields hold the same ISO-3166 alpha-2 code, in upper case.",
      "example": "ein_issuing_country: US · country: US — or GB and GB for a UK company number",
      "pitfalls": [
        "A US subsidiary of a foreign parent registers with US and its own EIN. The issuing country follows the identifier, not the head office."
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-026",
      "slug": "brd-026",
      "title": "An alternate identifier needs its type alongside it",
      "statement": "Where altBusinessId is supplied, altBusinessIdType must be one of DUNS, GIIN, LEI or NONE.",
      "rationale": "The alternate identifier is optional and strengthens verification when it is present, but a number with no type is a number nobody can look up — the registry rejects the pair rather than storing half of it. It usually happens when a DUNS number is added helpfully, from a procurement record that never carried a type field.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.alt_business_id + brand.alt_business_id_type",
      "severity": "LOW",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR"
      ],
      "codes": [
        {
          "provider": "TCR",
          "code": "501",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Set altBusinessIdType to the register the alternate number came from — DUNS for Dun & Bradstreet, GIIN for the IRS FATCA register, LEI for a legal entity identifier. If you do not have one, clear both fields rather than sending a bare number. Done when either both fields are populated or neither is.",
      "example": "alt_business_id: 123456789 · alt_business_id_type: DUNS",
      "notes": "The field is optional and validated only when present, which is why this is LOW rather than BLOCKING — but it will reject the whole brand submission, so it costs a round trip like any other field error.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-027",
      "slug": "brd-027",
      "title": "EIN must be old enough to have propagated to IRS records",
      "statement": "A newly issued EIN is not yet present in the records vetting providers query; registration fails until it propagates.",
      "rationale": "A newly issued EIN is not yet visible to the databases vetting providers query, so verification fails against a record that does not exist yet. No form correction fixes this — the only remedy is time, which is worth knowing before paying a non-refundable vetting fee.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.ein",
      "severity": "HIGH",
      "detectability": [
        "EXTERNAL_DATA",
        "HUMAN"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "AWS",
        "Twilio",
        "Bandwidth"
      ],
      "applicability": {
        "excludeEntityTypes": [
          "SOLE_PROPRIETOR"
        ]
      },
      "applicabilityText": "Applies when the brand is NOT a sole proprietor.",
      "universal": false,
      "remediation": "If your EIN was issued in the last 90 days, wait before submitting. No form correction fixes this — vetting queries a record that does not exist yet.",
      "notes": "Providers publish different windows (AWS 30 days, Twilio 30-90, Bandwidth 90). Strictest kept per the strict-superset model.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Was this EIN issued more than 90 days ago?",
        "howToCheck": [
          "Find the issue date printed on the CP-575 confirmation letter.",
          "Count the days to today. Under 90, wait rather than submit — providers publish windows from 30 to 90 days and the longest is the one worth planning against."
        ],
        "failureLooksLike": "An EIN issued three weeks ago matches nothing, and the rejection says the business could not be found rather than that the EIN is too new — so a perfectly correct name and address get edited over and over."
      }
    },
    {
      "id": "BRD-028",
      "slug": "brd-028",
      "title": "A business absent from the verification databases must upload its registration document",
      "statement": "Where the entity does not appear in third-party verification databases, an official registration or IRS document must be uploaded with the brand.",
      "rationale": "Commercial business databases lag reality by months, so a genuinely new company is missing from them for no fault of its own and the automated check returns \"entity not found\". The document upload is the intended route around that, not an escalation — but nothing in the form suggests it exists, so new businesses conclude they are ineligible and give up.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "registration document attachment",
      "severity": "BLOCKING",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EVIDENCE",
      "authorities": [
        "AWS",
        "Bandwidth"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Attach the CP-575 or 147C letter, or the state filing certificate, as a PDF with the registration. Scan the whole page rather than cropping to the name. Done when the document showing the legal name, the identifier and the address is attached to the submission.",
      "notes": "Whether the entity is present in the commercial databases is something only the provider can see. What the user has to do is have the document ready before submitting rather than after the rejection — the CP-575 for a US entity, or the incorporation certificate from the national register elsewhere — because the resubmission window is where most of the delay accumulates.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Do you have the registration document scanned and ready to attach before you submit, rather than after a rejection?",
        "howToCheck": [
          "For a US entity: the CP-575 or a 147C letter, or the state filing certificate.",
          "Elsewhere: the incorporation certificate from the national register.",
          "Scan the whole page, not a crop of the name — the document has to show the legal name, the identifier and the address together."
        ],
        "failureLooksLike": "A genuinely new company is missing from the commercial databases, reads the \"entity not found\" result as ineligibility, and abandons the registration — when the document upload was the intended route through."
      }
    },
    {
      "id": "BRD-032",
      "slug": "brd-032",
      "title": "Submit the identifier in the form the issuing country requires",
      "statement": "For a country on TCR's VAT-optimised list, submit only the numeric portion of the VAT ID; elsewhere submit the corporation registration number or national tax ID.",
      "rationale": "A European VAT number is normally written with its country prefix — GB123456789 — and that prefix is exactly what TCR's lookup does not want. The number is right, the format is wrong, and the rejection says the business could not be verified, which sends people to check their company name. For countries off the optimised list the whole identifier is different: the VAT number will not verify at all and the corporation registration number is what is wanted.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.ein",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "Telnyx",
        "AWS"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Strip the two-letter country prefix from a VAT number and submit the digits only. If your country is not on TCR's VAT-optimised list, submit the corporation registration number from your national companies register instead of the VAT number. Done when the identifier is the bare number the register itself would search on.",
      "example": "ein: 123456789 for a GB VAT registration written GB123456789 — the digits only",
      "pitfalls": [
        "Which countries are on the optimised list changes, and TCR publishes it rather than deriving it. Check the current list before assuming your country qualifies."
      ],
      "notes": "Merges the two branches of one decision (the catalog's BRD-032 and BRD-033): the numeric VAT portion on the optimised list, the corporation registration number off it. Only the first branch is mechanical — the check reports an identifier still carrying its country prefix. Choosing between VAT and corporation number needs the current TCR country list, which we do not hold, so the user has to confirm their country against it themselves before deciding which number to send.",
      "catalogIds": [
        "BRD-033"
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-034",
      "slug": "brd-034",
      "title": "Validate a non-US identifier against its home register before submitting",
      "statement": "A non-US registration identifier should be confirmed against the issuing country's official register before it is submitted.",
      "rationale": "A foreign brand only gets a few automated attempts before it lands in the appeal queue, and an identifier that is stale, superseded or transcribed wrongly burns one of them for no reason. The home register is free to search and authoritative, which makes this the cheapest five minutes in the whole non-US registration path.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.ein",
      "severity": "HIGH",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "HighLevel"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Look the number up before submitting: VIES for an EU VAT number, ABN Lookup for Australia, NZBN for New Zealand, the Companies Registry for Hong Kong, Companies House for the UK. Done when the register returns your company, spelled the way you are about to submit it.",
      "notes": "We cannot reach these registers. The user runs the lookup themselves and, crucially, copies the legal name back from the register rather than from their letterhead — the name the register holds is the one the vetting provider will compare against.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Did you look this identifier up in the issuing country's official register, and copy the legal name back from what the register returned?",
        "howToCheck": [
          "Search the authoritative register: VIES for an EU VAT number, ABN Lookup for Australia, NZBN for New Zealand, the Companies Registry for Hong Kong, Companies House for the UK.",
          "Copy the company name from the register's result, not from your letterhead. That is the name the vetting provider compares against."
        ],
        "failureLooksLike": "A number that is stale, superseded, or transcribed one digit wrong burns one of the few automated attempts a non-US brand gets before it lands in the appeal queue."
      }
    },
    {
      "id": "BRD-035",
      "slug": "brd-035",
      "title": "The country of registration must be on the permitted list",
      "statement": "A brand registered in a country outside TCR's permitted-country list cannot be registered at all.",
      "rationale": "This is an eligibility gate rather than a data problem: some countries are excluded from the US A2P framework entirely, usually for sanctions or fraud-rate reasons, and no amount of correct paperwork moves a brand from the wrong side of it. Finding out late is expensive because everything else in the onboarding will have succeeded first.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.country + brand.ein_issuing_country",
      "severity": "BLOCKING",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "TCR"
      ],
      "codes": [
        {
          "provider": "TCR",
          "code": "529",
          "remediable": false
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Check the country against TCR's current permitted list before collecting anything else from the customer. Where the country is excluded, the only route is a US or otherwise permitted entity that genuinely owns the customer relationship — not a nominee registration under someone else's name.",
      "notes": "TCR publishes and revises the list; we do not hold it. The user has to check their country against the current published list before starting, and must not work around an exclusion by registering under a related entity in a permitted country — that is a fabricated registration (BRD-286) and carries a much worse outcome than a refusal.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Is the country of registration on TCR's current permitted-country list?",
        "howToCheck": [
          "Check the country against the list TCR publishes and revises, before you collect anything else from the customer.",
          "Where the country is excluded, the only legitimate route is a US or otherwise permitted entity that genuinely owns the customer relationship."
        ],
        "failureLooksLike": "Everything else in the onboarding succeeds first and the eligibility gate is discovered last. Registering under a related entity in a permitted country to get around it is a fabricated registration, which is a far worse outcome than a refusal."
      }
    },
    {
      "id": "BRD-036",
      "slug": "brd-036",
      "title": "A non-US brand should expect automated identity verification to fail",
      "statement": "A brand registered outside the US will usually fail the initial automated identity check and must budget for an appeal or an external vet.",
      "rationale": "The automated check queries US business registers, so a foreign company is absent from them for the ordinary reason that it is foreign. The result is an UNVERIFIED brand and a rejection that reads like a data error, and teams spend days re-checking a perfectly correct name and address before discovering the path was never going to work. Knowing it in advance turns a mystery into a scheduled step.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.country",
      "severity": "HIGH",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "TCR"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Plan for the identity-status appeal before submitting: have the home-country registration certificate ready as a PDF, and expect to order an external vet if the appeal does not clear it. Do not change correct brand data in response to the first UNVERIFIED result.",
      "notes": "Not a defect in the registration and not fixable by editing it — this rule exists to set the expectation. What the user has to do themselves is gather the evidence an appeal will need (the official registration extract from their national register, in English or with a certified translation) and allow for the extra week the appeal takes.",
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Do you have the home-country registration extract ready as a PDF, in English or with a certified translation, before you submit?",
        "howToCheck": [
          "Download the official extract from your national register — Companies House, the Handelsregister, the ASIC extract, whichever applies.",
          "Confirm the legal name on it is spelled exactly as you are about to submit it.",
          "Budget an extra week for the identity appeal, and do not edit correct brand data in response to the first UNVERIFIED result."
        ],
        "failureLooksLike": "A correct non-US brand comes back UNVERIFIED because the automated check queries US registers only, and the team spends days re-checking a name and address that were right all along."
      }
    },
    {
      "id": "BRD-037",
      "slug": "brd-037",
      "title": "Low-Volume Standard is not available to a non-US brand that needs vetting",
      "statement": "A non-US brand cannot stay on the Low-Volume Standard class once additional vetting is required of it.",
      "rationale": "Low-Volume Standard is the cheap class that skips external vetting, and a foreign brand is exactly the case where vetting cannot be skipped. Choosing it is rational — the volumes are genuinely low — and it produces a registration that can never complete, because the class forbids the step the brand needs.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.country + brand class",
      "severity": "MEDIUM",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "HighLevel"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Register the non-US brand as Standard and order the external vet it will need. The throughput starts lower than a vetted US brand and rises once the vet completes. Done when the brand class is STANDARD rather than LOW_VOLUME_STANDARD.",
      "example": "brand_class: STANDARD · country: GB — rather than LOW_VOLUME_STANDARD",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-038",
      "slug": "brd-038",
      "title": "Some providers require an external vet for every non-US brand",
      "statement": "At least one provider requires external vetting on every non-US customer before the brand can be used.",
      "rationale": "Where this applies it is a precondition rather than a remedy: the brand does not proceed at all until the vet is bought, so discovering it after the customer's data is collected wastes the submission and the fee for the class of vet that was ordered first. It is easy to miss because the requirement sits in the provider's onboarding terms rather than in any field validation.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.country + external vet record",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Vonage"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Order the external vet before submitting the brand, and budget its fee into the customer's onboarding. Done when a completed vet is attached to a non-US brand on a provider that requires one.",
      "notes": "Conditional on the submission target — Vonage states it explicitly for every non-US customer — and NOT tagged with `providers`, because the tag budget is spent on genuine baseline divergences and this one is checkable from the target we already hold. The condition lives in the check, which passes immediately for a US brand and reports UNCLEAR when the target is unknown. What the user must confirm themselves is whether their own provider imposes the same precondition: it is in the onboarding terms, not in any API error.",
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Have you checked your provider's onboarding terms for a mandatory external vet on non-US customers, and budgeted its fee?",
        "howToCheck": [
          "Read the provider's onboarding or acceptable-use terms rather than the API reference — the requirement lives there and produces no field validation error.",
          "Where it applies, order the vet before submitting the brand, and price it into the customer's onboarding."
        ],
        "failureLooksLike": "The brand is submitted, the fee for the wrong class of vet is spent first, and the requirement surfaces only as a support answer after the customer's data is already collected."
      }
    },
    {
      "id": "BRD-039",
      "slug": "brd-039",
      "title": "The sending-volume tier decides whether the sole-proprietor path is available",
      "statement": "A registration that requests a volume tier requiring a tax ID cannot be filed on the sole-proprietor path.",
      "rationale": "The sole-proprietor tier trades verification for throughput: it exists because an individual has no EIN, and it caps sending hard as a consequence. Choosing the tier and then requesting a volume it does not support produces a registration that is internally contradictory, and the platform resolves the contradiction by refusing the tier rather than by lowering the volume. Customers reach it by picking their plan first and their entity type second.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.entity_type + requested volume tier",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Textedly",
        "Twilio"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30903",
          "remediable": true
        }
      ],
      "applicability": {
        "entityTypes": [
          "SOLE_PROPRIETOR"
        ]
      },
      "applicabilityText": "Applies when the brand is a sole proprietor.",
      "universal": false,
      "remediation": "Either drop to the volume the sole-proprietor tier supports — roughly 1,000 messages a day — or obtain an EIN and register as a standard brand at the volume you actually need. Done when the requested class and the entity type describe the same tier.",
      "example": "entity_type: SOLE_PROPRIETOR with no brand class above it — or entity_type: PRIVATE_PROFIT with brand_class: STANDARD",
      "pitfalls": [
        "The cap is enforced by the CSP rather than by the carrier, so the traffic is not rejected message by message — it is throttled or the account is reviewed, which is harder to diagnose than a rejection."
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-040",
      "slug": "brd-040",
      "title": "Entity type must be one of the five supported values",
      "statement": "entityType must be exactly one of PRIVATE_PROFIT, PUBLIC_PROFIT, NON_PROFIT, GOVERNMENT or SOLE_PROPRIETOR.",
      "rationale": "Entity type decides which verification path runs, which use cases are available, and which other fields are mandatory, so a value outside the enum does not degrade gracefully — it rejects at the API boundary before any of that is evaluated. Integrations produce this by mapping an internal CRM value straight through.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.entity_type",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "AWS",
        "Bandwidth",
        "Twilio"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Set entityType to one of the five values exactly, in upper case with underscores. Done when the submitted string is character-identical to one of them.",
      "example": "entity_type: PRIVATE_PROFIT",
      "pitfalls": [
        "LLC, Corporation and Partnership are legal forms rather than entity types — nearly all of them register as PRIVATE_PROFIT."
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-041",
      "slug": "brd-041",
      "title": "The entity type must match the classification on the tax record",
      "statement": "The selected entity type must match how the business is classified on its tax record, with documentation where the classification is not machine-verifiable.",
      "rationale": "Entity type drives which verification path runs and which use cases open, so it is checked against the tax classification rather than taken on trust. Honest mismatches are everywhere: an LLC taxed as an S-corp, a member-owned co-operative, a non-profit that never completed its exemption. The registrant picks the description that feels true and the record says something else.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.entity_type vs the tax record",
      "severity": "BLOCKING",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "TCR",
        "Twilio",
        "Bandwidth"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30796",
          "remediable": true
        },
        {
          "provider": "Twilio",
          "code": "30797",
          "remediable": true
        },
        {
          "provider": "Twilio",
          "code": "30798",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Match the entity type to the classification on the IRS letter rather than to how the business describes itself. Nearly every commercial company — LLC, S-corp, C-corp, partnership — is PRIVATE_PROFIT. Where the classification is genuinely unusual, attach the determination letter with the registration.",
      "notes": "The tax record is not something we can read. The user has to check their CP-575 or determination letter and pick the entity type that matches it — and where the two genuinely differ, attach the document rather than arguing the point in an appeal, because the reviewer is comparing against the same record.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Does the entity type you selected match the classification on the IRS letter, rather than how the business describes itself?",
        "howToCheck": [
          "Read the classification on the CP-575 or the determination letter.",
          "Nearly every commercial company — LLC, S-corp, C-corp, partnership — is PRIVATE_PROFIT, whatever it calls itself internally.",
          "Where the classification is genuinely unusual (a co-operative, a mutual association), attach the determination letter with the registration."
        ],
        "failureLooksLike": "An LLC taxed as an S-corp picks the description that feels most accurate, and the record says something else. The mismatch fails the verification path rather than merely re-grading it."
      }
    },
    {
      "id": "BRD-042",
      "slug": "brd-042",
      "title": "A non-US organisation registers as private for profit",
      "statement": "A brand whose country of registration is not the US must be PRIVATE_PROFIT — GOVERNMENT and NON_PROFIT are US-only classifications.",
      "rationale": "The non-profit and government paths verify against US registers — the IRS exempt-organisation file, US government domains — so a foreign charity selecting NON_PROFIT is checked against a database it cannot appear in and fails for looking fraudulent rather than foreign. Registering as PRIVATE_PROFIT is not a demotion; it is the only classification the verification chain can actually resolve.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.entity_type + brand.country",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "AWS"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Set entityType to PRIVATE_PROFIT and supply the home country's business registration number. Done when the entity type is PRIVATE_PROFIT and the identifier is the one that country issues.",
      "example": "entity_type: PRIVATE_PROFIT · country: GB · identifier: the UK company number",
      "pitfalls": [
        "A foreign non-profit that holds a US EIN can register as NON_PROFIT on the strength of it — the test is the US tax record, not where the charity operates."
      ],
      "notes": "Also discharges BRD-052, which states the same requirement from the non-profit side: NON_PROFIT is available only to a US-based organisation or one holding a US EIN. The check already carries that exception, so the two are one rule rather than two.",
      "catalogIds": [
        "BRD-052"
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-043",
      "slug": "brd-043",
      "title": "The business-type field takes its own enum, not the entity type",
      "statement": "Where a business_type is declared, it must be one of Co-operative, Corporation, Limited Liability Corporation, Non-profit Corporation or Partnership.",
      "rationale": "This is a second classification field with a different vocabulary from entityType, on the same form, describing the same company. Populating it from the entity type — PRIVATE_PROFIT, NON_PROFIT — produces values that are not in its enum, and the submission fails validation on a field the user believed they had already answered further up the page.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.business_type",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Twilio"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30701",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Set business_type to the legal form of the company — an LLC is \"Limited Liability Corporation\", an Inc is \"Corporation\" — and leave entityType as the TCR classification. Done when the two fields hold values from their own lists rather than from each other's.",
      "example": "business_type: Limited Liability Corporation · entity_type: PRIVATE_PROFIT — for Acme Coffee Co, LLC",
      "notes": "Twilio Trust Hub carries this field and TCR does not, so it is checked only where it is populated: a registration that never declares one passes. Where the submission target is Twilio the field is mandatory, and the check says so rather than passing silently.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-044",
      "slug": "brd-044",
      "title": "Changing an identity field re-runs verification, and costs the fee again",
      "statement": "Any change to entity type, EIN, EIN issuing country or legal name re-runs brand verification and resets the identity status.",
      "rationale": "These four fields are the identity itself, so editing one is not a correction to a verified brand — it is a new claim about who the business is, and the registry treats it that way: the status drops back, the fee is charged again, and any completed vet expires with it. Teams fixing a typo in a legal name are routinely surprised to find a working brand back in UNVERIFIED and their campaigns blocked behind it.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.entity_type + brand.ein + brand.ein_issuing_country + brand.company_name",
      "severity": "HIGH",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Vonage",
        "TCR",
        "Twilio"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Batch every identity correction into one edit rather than making them one at a time — each round trip charges the verification fee again. Expect the brand to return to UNVERIFIED and campaign registration to be blocked until it clears, and do not schedule the change on the day of a send.",
      "notes": "Absorbs OPS-343, which states the same trigger together with its two consequences: the identity reset, and the vet expiry that BRD-222 covers. The re-verification itself happens at the registry and takes as long as it takes — what the user has to do is time the change deliberately and be ready to re-order any external vet that expires with it.",
      "catalogIds": [
        "OPS-343"
      ],
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Are all of your identity corrections — entity type, EIN, EIN country, legal name — batched into a single edit, made on a day you are not sending?",
        "howToCheck": [
          "List every identity field you intend to change and make them in one operation. Each separate round trip charges the verification fee again.",
          "Expect the brand to drop to UNVERIFIED and campaign registration to be blocked until it clears, and expect any completed external vet to expire with it."
        ],
        "failureLooksLike": "A typo in the legal name is fixed on a Friday. A working brand is back in UNVERIFIED, its vet has expired, its campaigns are blocked, and the fee has been charged twice."
      }
    },
    {
      "id": "BRD-045",
      "slug": "brd-045",
      "title": "PUBLIC_PROFIT means the shares actually trade",
      "statement": "The PUBLIC_PROFIT classification is available only to a company whose shares are genuinely publicly traded.",
      "rationale": "Public companies start at the top carrier trust class and get the throughput that comes with it, so the claim is checked against an exchange listing rather than taken from the form. The mistake is usually a large private company reading \"public\" as \"well known\", and the result is not a downgrade — it is a failed identity verification, because the ticker matched nothing.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.entity_type",
      "severity": "BLOCKING",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Twilio",
        "TCR"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30796",
          "remediable": true
        }
      ],
      "applicability": {
        "entityTypes": [
          "PUBLIC_PROFIT"
        ]
      },
      "applicabilityText": "Applies when the brand is a public company.",
      "universal": false,
      "remediation": "Register as PRIVATE_PROFIT unless the company has a ticker on a recognised exchange. A private company with high volume gets there through external vetting instead, which raises throughput on evidence rather than on classification.",
      "notes": "The listing is checked against exchange data we do not hold. What the user has to confirm themselves is that the company files with the SEC and its shares trade under the symbol being submitted — a company that was public and has since been taken private is the case that catches people, because the ticker is still remembered.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Do this company's shares trade today, under the symbol on this brand, on a recognised exchange?",
        "howToCheck": [
          "Look the ticker up and confirm it returns this company — not a similarly named one, and not a listing that has since been withdrawn.",
          "Confirm the company still files with the SEC. A company taken private keeps its remembered ticker and loses the classification."
        ],
        "failureLooksLike": "A large, well-known private company reads \"public\" as \"well known\". The result is not a downgrade to private — it is a failed identity verification, because the ticker matched nothing."
      }
    },
    {
      "id": "BRD-047",
      "slug": "brd-047",
      "title": "Public companies must supply stock symbol and exchange",
      "statement": "A PUBLIC_PROFIT brand must declare both its ticker symbol and the exchange it trades on.",
      "rationale": "Public companies get elevated trust and throughput, and the ticker is what lets a vetting provider confirm the claim against an exchange listing. Without both symbol and exchange the claim cannot be checked, so it is refused.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.stock_symbol + brand.stock_exchange",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "Twilio",
        "Telnyx"
      ],
      "applicability": {
        "entityTypes": [
          "PUBLIC_PROFIT"
        ]
      },
      "applicabilityText": "Applies when the brand is a public company.",
      "universal": false,
      "remediation": "Enter the ticker symbol and the exchange (e.g. NASDAQ, NYSE).",
      "example": "Stock symbol: ACME · Exchange: NASDAQ",
      "catalogIds": [
        "BRD-046"
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-048",
      "slug": "brd-048",
      "title": "The stock exchange must be a recognised enum value",
      "statement": "A public company's stock exchange must be one of the supported registry values.",
      "rationale": "The exchange and symbol together are how a public brand is matched to a listing, so a free-text exchange name matches nothing and drops the brand out of the public-company path it was registered for. People type what they say aloud — \"Nasdaq\", \"New York Stock Exchange\" — rather than the code the enum wants.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.stock_exchange",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "Telnyx"
      ],
      "applicability": {
        "entityTypes": [
          "PUBLIC_PROFIT"
        ]
      },
      "applicabilityText": "Applies when the brand is a public company.",
      "universal": false,
      "remediation": "Pick the exchange code from the registry list rather than typing the name. Done when the value is one of the short codes — NASDAQ, NYSE, LON, TSX and the rest — in upper case.",
      "example": "stock_exchange: NASDAQ · stock_symbol: ACME",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-049",
      "slug": "brd-049",
      "title": "Stock fields must be empty for non-public entities",
      "statement": "stockSymbol and stockExchange must be omitted entirely when the entity type is not PUBLIC_PROFIT.",
      "rationale": "A populated ticker on a private company is an internally contradictory registration, and vetting treats contradictions as failed identity verification rather than as a harmless extra field. It usually happens when a form is copied from a template or a previous registration.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.stock_symbol + brand.stock_exchange",
      "severity": "HIGH",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "Twilio"
      ],
      "applicability": {
        "excludeEntityTypes": [
          "PUBLIC_PROFIT"
        ]
      },
      "applicabilityText": "Applies when the brand is NOT a public company.",
      "universal": false,
      "remediation": "Clear both stock fields. They apply only to publicly traded companies.",
      "example": "Stock symbol: (empty) · Stock exchange: (empty)",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-050",
      "slug": "brd-050",
      "title": "A stock symbol may back only one brand",
      "statement": "A stock symbol already registered against another brand cannot be used again.",
      "rationale": "The ticker is treated as an identity key, so two brands claiming the same symbol is read as one of them being wrong. Large groups hit this legitimately: a subsidiary registering under the parent's ticker collides with the parent's own brand, and the subsidiary has no visibility of it.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.stock_symbol",
      "severity": "BLOCKING",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Twilio",
        "TCR"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30703",
          "remediable": true
        }
      ],
      "applicability": {
        "entityTypes": [
          "PUBLIC_PROFIT"
        ]
      },
      "applicabilityText": "Applies when the brand is a public company.",
      "universal": false,
      "remediation": "Register the subsidiary under its own entity type and identifier rather than the listed parent's ticker. Where the listed entity itself is being registered twice, share or transfer the existing brand instead of creating a second one.",
      "notes": "The collision is against every brand in the registry, which we cannot see. The user has to establish whether anyone in their group — or a former vendor — has already registered a brand under this ticker, and if so route the traffic through that brand rather than duplicating it.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Has anyone else in your group, or a former vendor, already registered a brand under this ticker?",
        "howToCheck": [
          "Ask the parent company's messaging or IT owner whether a 10DLC brand already exists for the listed entity.",
          "Where one does, route this traffic through the existing brand rather than creating a second one; a subsidiary registers under its own entity and identifier, not the listed parent's ticker."
        ],
        "failureLooksLike": "A subsidiary registers under the parent's ticker and collides with the parent's own brand — a record it has no visibility of and cannot query."
      }
    },
    {
      "id": "BRD-051",
      "slug": "brd-051",
      "title": "Russell 3000 membership sets the starting carrier class",
      "statement": "A verified public brand on the Russell 3000 starts at the top carrier classes; one that is not starts at the bottom until it is vetted.",
      "rationale": "The same PUBLIC_PROFIT classification produces very different throughput depending on an index membership nobody is asked about, so two public companies register identically and one can send a hundred times more than the other. Knowing which side you are on before launch is the difference between planning an external vet and discovering mid-campaign that the throughput is not there.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.company_name + the Russell 3000 list",
      "severity": "MEDIUM",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "TCR",
        "T-Mobile",
        "AT&T",
        "Infobip",
        "Bandwidth"
      ],
      "applicability": {
        "entityTypes": [
          "PUBLIC_PROFIT"
        ]
      },
      "applicabilityText": "Applies when the brand is a public company.",
      "universal": false,
      "remediation": "Check whether the company is a current Russell 3000 constituent. If it is not, plan an external vet into the launch schedule rather than assuming the public classification is enough — the starting class without one is the lowest tier, not the highest.",
      "notes": "Informational rather than a rejection: nothing fails on this. The user checks the current constituent list themselves — it is published annually and reconstituted each June — and uses the answer to decide whether to buy a vet before launch.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Is this company a current Russell 3000 constituent?",
        "howToCheck": [
          "Check the published constituent list — it is reconstituted each June, so a company can drop off without anyone noticing.",
          "If it is not on the list, plan an external vet into the launch schedule: the starting class without one is the lowest tier, not the highest."
        ],
        "failureLooksLike": "Two public companies register identically and one can send a hundred times more than the other. Nothing fails; the throughput simply is not there when the campaign goes live."
      }
    },
    {
      "id": "BRD-053",
      "slug": "brd-053",
      "title": "Tax-exempt status must be verified against the IRS registers",
      "statement": "A NON_PROFIT registration must be backed by an EIN that appears in the IRS Tax-Exempt Organization Search.",
      "rationale": "The non-profit classification and the charity use case both rest on a status the IRS publishes and anyone can check, so the claim is verified rather than accepted. Organisations that operate not for profit but never completed a 501(c) application — community groups, mutual associations, clubs — are outside the register and are refused for a status they never actually held, which is a difficult conversation to have after launch.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.ein",
      "severity": "HIGH",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Twilio",
        "Plivo",
        "HighLevel"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30798",
          "remediable": true
        }
      ],
      "applicability": {
        "entityTypes": [
          "NON_PROFIT"
        ]
      },
      "applicabilityText": "Applies when the brand is a non-profit.",
      "universal": false,
      "remediation": "Search the IRS Tax-Exempt Organization Search for the EIN before submitting, and register as PRIVATE_PROFIT if it does not appear. Where the exemption is genuine but the register is out of date, expect to attach the determination letter to an appeal.",
      "notes": "Absorbs BRD-061, which is the same lookup used to establish a TCPA exemption rather than an entity type. We hold no IRS data, so the user runs the search themselves — it is free and public — and should do it before choosing the entity type rather than after the rejection, because switching entity type re-runs verification (BRD-044).",
      "catalogIds": [
        "BRD-061"
      ],
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Does this EIN appear in the IRS Tax-Exempt Organization Search?",
        "howToCheck": [
          "Search the EIN at the IRS Tax-Exempt Organization Search. It is free and public.",
          "If it does not appear, register as PRIVATE_PROFIT — and do it before submitting, because changing entity type afterwards re-runs verification and charges the fee again.",
          "Genuinely exempt but absent from the register: expect to attach the determination letter to an appeal."
        ],
        "failureLooksLike": "A community group, mutual association or club that operates not for profit but never completed a 501(c) application is refused for a status it never actually held — a hard conversation to have after launch."
      }
    },
    {
      "id": "BRD-055",
      "slug": "brd-055",
      "title": "Non-profit classification must be consistent across every field",
      "statement": "A non-profit brand must be marked as non-profit consistently across entity type, vertical, and any company-type field.",
      "rationale": "The three fields feed different downstream systems, and a brand marked NON_PROFIT with a commercial vertical produces a registration that contradicts itself. Charity and political use-case eligibility both key off this classification, so an inconsistency blocks the use cases the organisation actually needs.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.entity_type + brand.vertical",
      "severity": "HIGH",
      "detectability": [
        "AI_FORM"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "Twilio",
        "Infobip"
      ],
      "applicability": {
        "entityTypes": [
          "NON_PROFIT"
        ]
      },
      "applicabilityText": "Applies when the brand is a non-profit.",
      "universal": false,
      "remediation": "Set the vertical to the non-profit / NGO value alongside the NON_PROFIT entity type, and declare the tax-exempt status on the brand record.",
      "example": "Entity type: NON_PROFIT · Vertical: NGO · Tax exempt status: 501(c)(3)",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-057",
      "slug": "brd-057",
      "title": "A charity brand needs an arm's-length accreditation",
      "statement": "A brand running the charity use case must be accredited by at least one independent non-profit accreditation body.",
      "rationale": "The charity use case carries relief that ordinary marketing does not get, and tax-exempt status alone is a low bar — it says the IRS accepted a form, not that the organisation is what it says. An accreditation from a body that examines finances and governance is the evidence carriers actually want, and a charity that has never sought one finds this out at the point of registration rather than at the point of applying.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "accreditation listing URL",
      "severity": "BLOCKING",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "T-Mobile",
        "CTIA"
      ],
      "applicability": {
        "useCases": [
          "CHARITY"
        ]
      },
      "applicabilityText": "Applies when the use case is CHARITY.",
      "universal": false,
      "remediation": "Obtain a current BBB Wise Giving Alliance report or a current three- or four-star Charity Navigator rating, and keep the listing URL with the registration. Where neither is held, register the messaging under a use case that does not claim charitable standing until accreditation is in place.",
      "notes": "We cannot check an accreditation listing. The user has to hold one before registering: the BBB report takes weeks to obtain and Charity Navigator ratings are computed from filed returns, so neither is available on demand — this is a lead-time item, not a form field.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Do you hold a current BBB Wise Giving Alliance report, or a current three- or four-star Charity Navigator rating, with its listing URL to hand?",
        "howToCheck": [
          "Look the organisation up on both and note the listing URL for whichever it holds.",
          "Check the rating is current rather than historical — Charity Navigator ratings are computed from filed returns and lapse.",
          "Neither in place: this is a lead-time item. A BBB report takes weeks, so register under a use case that does not claim charitable standing until it lands."
        ],
        "failureLooksLike": "Tax-exempt status is treated as sufficient. It says the IRS accepted a form, not that an independent body examined the finances — which is the evidence carriers actually want."
      }
    },
    {
      "id": "BRD-058",
      "slug": "brd-058",
      "title": "Keep the charity evidence bundle together",
      "statement": "A charity brand must retain its organisation name, EIN, charity website and accreditation listing URL as proof of 501(c)(3) standing.",
      "rationale": "The charity claim is re-examined whenever a campaign under it is reviewed, and the four items are asked for together because each covers a different substitution — a real charity's name with someone else's EIN, a real EIN with a lookalike website. Charities that assembled the evidence once for the original submission and did not keep it end up rebuilding it under time pressure during a review.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "charity evidence bundle",
      "severity": "BLOCKING",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EVIDENCE",
      "authorities": [
        "T-Mobile",
        "Bandwidth",
        "Infobip"
      ],
      "applicability": {
        "useCases": [
          "CHARITY"
        ]
      },
      "applicabilityText": "Applies when the use case is CHARITY.",
      "universal": false,
      "remediation": "Keep one folder holding the registered organisation name, the EIN, the charity website URL and the accreditation listing URL, and keep it current — a lapsed Charity Navigator rating invalidates the bundle. Done when all four can be produced in a single reply to a review request.",
      "notes": "Evidence only the organisation holds. What the user must do is assemble the four items now and store them where whoever answers a carrier review can reach them, rather than relying on the person who filed the registration still being there.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Can one person produce all four items — registered organisation name, EIN, charity website, accreditation listing URL — in a single reply to a carrier review?",
        "howToCheck": [
          "Put the four in one folder where whoever answers a review can reach it, not with the person who happened to file the registration.",
          "Re-check the accreditation listing periodically: a lapsed Charity Navigator rating invalidates the bundle."
        ],
        "failureLooksLike": "The evidence was assembled once for the original submission and never kept. A campaign review arrives with a deadline and the bundle is rebuilt under time pressure."
      }
    },
    {
      "id": "BRD-059",
      "slug": "brd-059",
      "title": "A unified fundraising short code needs five years of operating history",
      "statement": "A charity seeking a single unified short code for fundraising must demonstrate at least five years of operation.",
      "rationale": "Unified fundraising codes are shared infrastructure with a high abuse value — a fraudulent appeal on a recognised code damages every charity on it — so the entry bar is time in operation rather than paperwork. Newer charities can still message; what they cannot do is join the unified code, and planning a campaign around one is the expensive way to discover that.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "charity operating history",
      "severity": "MEDIUM",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "CTIA"
      ],
      "applicability": {
        "useCases": [
          "CHARITY"
        ]
      },
      "applicabilityText": "Applies when the use case is CHARITY.",
      "universal": false,
      "remediation": "Plan the campaign on a 10DLC number or a dedicated short code where the organisation is younger than five years. Revisit the unified code once the operating history is there; nothing about the registration changes in the meantime.",
      "notes": "A short-code path requirement rather than a 10DLC one, recorded here because charities plan across both. The user has to check their own incorporation date against the five-year bar before committing to a unified-code campaign — no part of the 10DLC registration will tell them.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Has this organisation been operating for at least five years, counting from its incorporation date?",
        "howToCheck": [
          "Find the incorporation or determination date on the organisation's founding documents.",
          "Under five years, plan the campaign on a 10DLC number or a dedicated short code and revisit the unified fundraising code later — nothing about the registration changes in the meantime."
        ],
        "failureLooksLike": "A four-year-old charity builds its whole appeal around a unified short code, and finds out at the point of application that the bar is time in operation and there is no paperwork that shortens it."
      }
    },
    {
      "id": "BRD-060",
      "slug": "brd-060",
      "title": "A 501(c)(3) may not run certain use cases",
      "statement": "A brand holding 501(c)(3) status must not register the Agents & Franchises, Carrier Exempt, Proxy, Social or Sweepstake use cases.",
      "rationale": "These five use cases are commercial mechanics — reselling reach, sweepstakes promotion, proxy messaging — and a charitable exemption is granted on the basis that the organisation is not doing them. The block protects the exemption as much as the channel: a charity that runs a sweepstakes campaign on its exempt status has a problem considerably larger than a rejected registration.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.tax_exempt_status + campaign.use_case",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC",
        "EXTERNAL_DATA"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR"
      ],
      "applicability": {
        "entityTypes": [
          "NON_PROFIT"
        ]
      },
      "applicabilityText": "Applies when the brand is a non-profit.",
      "universal": false,
      "remediation": "Choose a use case the exemption permits — CHARITY for fundraising and appeals, ACCOUNT_NOTIFICATION for supporter records, CUSTOMER_CARE for enquiries. If the programme really is a sweepstake or an agent network, it belongs on a separate commercial brand rather than on the exempt entity. Done when the use case is one a 501(c)(3) may hold.",
      "example": "tax_exempt_status: 501(c)(3) · use_case: CHARITY — not SWEEPSTAKE",
      "notes": "Decidable from the two declared values, which is why it carries a check even though the catalog grades it EXTERNAL_DATA — the external half is confirming the 501(c)(3) status itself, which is BRD-053. The neighbouring rule XBC-002 asks the opposite question: whether a brand claiming the CHARITY use case actually holds the status.",
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Is the 501(c)(3) status on this brand real and current, and is the use case one an exempt organisation may hold?",
        "howToCheck": [
          "Confirm the exemption in the IRS Tax-Exempt Organization Search.",
          "Check the use case is not Agents & Franchises, Carrier Exempt, Proxy, Social or Sweepstake — those five are commercial mechanics an exemption is granted on the basis of not doing."
        ],
        "failureLooksLike": "A charity runs a sweepstake campaign on its exempt status. The rejected registration is the smallest of its problems."
      }
    },
    {
      "id": "BRD-062",
      "slug": "brd-062",
      "title": "GOVERNMENT is for US government bodies only",
      "statement": "The GOVERNMENT entity type is reserved for US federal, state or local government bodies.",
      "rationale": "The government classification carries the top carrier trust class and the throughput that comes with it, so it is verified strictly and misuse is treated as an attempt to obtain that standing. Contractors, public utilities and government-funded non-profits reach for it reasonably and are all outside it.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.entity_type",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "AWS",
        "Bandwidth"
      ],
      "applicability": {
        "entityTypes": [
          "GOVERNMENT"
        ]
      },
      "applicabilityText": "Applies when the brand is a government.",
      "universal": false,
      "remediation": "Register as GOVERNMENT only if the entity is itself a US federal, state, county or municipal body. A contractor or a grant-funded organisation registers under its own classification — usually PRIVATE_PROFIT or NON_PROFIT. Done when the entity type matches what the organisation legally is.",
      "example": "entity_type: GOVERNMENT · country: US — a city, county, state agency or federal department",
      "notes": "Only the country half is checkable here. Whether the organisation IS a government body is EXTERNAL_DATA, verified against a .gov domain and the vetting report, so a US-country GOVERNMENT brand passes this rule and may still fail vetting.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-064",
      "slug": "brd-064",
      "title": "A government brand must carry the government attribute to get its class",
      "statement": "A GOVERNMENT brand must have the governmentEntity attribute set before the top carrier class can be assumed.",
      "rationale": "The entity type and the attribute are separate: registering as GOVERNMENT selects the classification, but the throughput comes from an optional attribute that verification sets — and when it does not, the brand sits at the bottom carrier class with no error anywhere. Agencies plan capacity on the class they expected and find out on the day of a mass notification, which is the worst possible moment for a government sender.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.optional_attributes.government_entity",
      "severity": "HIGH",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "AT&T",
        "T-Mobile"
      ],
      "applicability": {
        "entityTypes": [
          "GOVERNMENT"
        ]
      },
      "applicabilityText": "Applies when the brand is a government.",
      "universal": false,
      "remediation": "Check the brand record for the governmentEntity attribute after verification completes. If it is missing, file an appeal in the \"Verify Government status\" category with the authorising statute or the agency's .gov domain as evidence rather than re-registering. Done when the attribute reads true on the brand.",
      "example": "entity_type: GOVERNMENT · government_entity: true — both, not just the entity type",
      "pitfalls": [
        "The attribute is what carriers read, not the entity type, so a GOVERNMENT brand without it is treated as an ordinary standard brand however it was registered."
      ],
      "notes": "BRD-263 is the appeal route when this attribute is missing on an otherwise VERIFIED brand; this rule is the detection.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-065",
      "slug": "brd-065",
      "title": "Sole proprietor must have no EIN",
      "statement": "The SOLE_PROPRIETOR tier is for a US individual without an EIN. Supplying an EIN disqualifies the registration.",
      "rationale": "The sole proprietor tier is defined as the path for an individual WITHOUT an EIN. Supplying one is a contradiction the platform reads as a misfiled standard brand, and it is corrected by changing tier rather than by editing the field.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.ein",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "Twilio",
        "Telnyx"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30903",
          "remediable": true
        },
        {
          "provider": "Twilio",
          "code": "30915",
          "remediable": true
        }
      ],
      "applicability": {
        "entityTypes": [
          "SOLE_PROPRIETOR"
        ]
      },
      "applicabilityText": "Applies when the brand is a sole proprietor.",
      "universal": false,
      "remediation": "If the business has an EIN, register it as a standard brand (Private/Public/Non-profit) instead of Sole Proprietor. If it genuinely has no EIN, clear the EIN field.",
      "example": "EIN: (leave empty)",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-067",
      "slug": "brd-067",
      "title": "A business trading under a DBA belongs on the standard tier",
      "statement": "A sole-proprietor registration that declares a DBA must be re-filed as a standard brand.",
      "rationale": "The sole-proprietor tier is for an individual with no business registration at all. A DBA is a business registration — it is filed with a county or state — so declaring one is evidence the applicant qualifies for, and therefore must use, the standard tier. The tiers are not interchangeable: the sole-proprietor path caps throughput hard and verifies by text message, which is a worse deal than the applicant is entitled to.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.dba + brand.entity_type",
      "severity": "HIGH",
      "detectability": [
        "AI_FORM"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Twilio"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30914",
          "remediable": true
        },
        {
          "provider": "Twilio",
          "code": "30918",
          "remediable": true
        }
      ],
      "applicability": {
        "entityTypes": [
          "SOLE_PROPRIETOR"
        ]
      },
      "applicabilityText": "Applies when the brand is a sole proprietor.",
      "universal": false,
      "remediation": "Apply for an EIN — it is free and issued immediately online — and register as a standard brand with the DBA in its own field. If you would rather stay on the sole-proprietor tier, clear the DBA and register under your own name only. Done when the tier and the presence of a DBA agree.",
      "example": "entity_type: PRIVATE_PROFIT · company_name: Jane Doe Bodywork, LLC · dba: Jane Doe Bodywork — rather than the sole-proprietor tier with a DBA attached",
      "pitfalls": [
        "Waiting for a new EIN to propagate is BRD-027 and costs up to 90 days, so apply for it before you need the brand rather than after this rejection."
      ],
      "notes": "A different disqualifier from BRD-065 (an EIN present on a sole-proprietor brand) with a different fix, which is why the catalog keeps them apart.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-068",
      "slug": "brd-068",
      "title": "Sole proprietor brand name must be a person, not a company",
      "statement": "The sole proprietor brand name must be the individual’s first and last name — never an LLC, Inc, Corp or other registered entity name.",
      "rationale": "A sole proprietor is a natural person, so the brand name is a person's name. A corporate suffix proves a registered entity exists behind it, which means the business qualifies for — and is required to use — the standard tier instead.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.company_name",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "Twilio"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30914",
          "remediable": true
        }
      ],
      "applicability": {
        "entityTypes": [
          "SOLE_PROPRIETOR"
        ]
      },
      "applicabilityText": "Applies when the brand is a sole proprietor.",
      "universal": false,
      "remediation": "Enter the individual’s legal first and last name. A business name with a corporate suffix means the entity is not a sole proprietor for 10DLC purposes — register it as a standard brand.",
      "example": "Brand name: Jane Doe",
      "catalogIds": [
        "BRD-069"
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-070",
      "slug": "brd-070",
      "title": "The verification number must be a real US or Canadian mobile",
      "statement": "The sole-proprietor mobile number must be an active US or Canadian wireless number in E.164 that can receive SMS.",
      "rationale": "This number is the entire identity check on this tier — there is no tax record behind it — so it has to be a handset a person answers, not a landline, a VoIP line, or a number from the platform being registered on. A business owner who supplies their office number gets no OTP, no error, and a brand that stays UNVERIFIED with nothing on the form to explain it.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.mobile_phone",
      "severity": "BLOCKING",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "TCR",
        "Twilio",
        "Telnyx",
        "Vonage"
      ],
      "codes": [
        {
          "provider": "TCR",
          "code": "551",
          "remediable": true
        },
        {
          "provider": "Twilio",
          "code": "30751",
          "remediable": true
        }
      ],
      "applicability": {
        "entityTypes": [
          "SOLE_PROPRIETOR"
        ]
      },
      "applicabilityText": "Applies when the brand is a sole proprietor.",
      "universal": false,
      "remediation": "Supply the owner's personal mobile in E.164 — +1 followed by ten digits — and have the handset to hand when the registration is submitted. Send yourself a test text first if you are unsure the line receives SMS.",
      "notes": "The line type is a carrier lookup we cannot run. What the user has to confirm themselves is that the number is a genuine wireless line on a US or Canadian carrier: office VoIP numbers, Google Voice numbers and numbers issued by a CPaaS all look correct in the field and none of them will complete the OTP.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Is the verification number a genuine wireless line on a US or Canadian consumer carrier, able to receive SMS today?",
        "howToCheck": [
          "Text the number from another phone and confirm it arrives on a handset.",
          "Rule out the three lookalikes: an office VoIP line, a Google Voice number, and a number issued by a messaging provider. All three look correct in the field and none will complete the OTP.",
          "Enter it in E.164 — +1 followed by the ten digits."
        ],
        "failureLooksLike": "The owner supplies the office number. No OTP arrives, no error is shown, and the brand sits UNVERIFIED with nothing on the form to explain why."
      }
    },
    {
      "id": "BRD-072",
      "slug": "brd-072",
      "title": "Sole proprietor mobile number has a reuse limit",
      "statement": "A mobile number used for sole proprietor OTP verification may back at most three brand registrations, and must not be a CPaaS-issued number.",
      "rationale": "The verified mobile number is the only real identity check the sole proprietor tier has, so its reuse is capped and CPaaS-issued numbers are refused — otherwise one operator could mint unlimited \"individuals\". The 24-hour reply window is short and unforgiving.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.phone",
      "severity": "BLOCKING",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Twilio",
        "TCR"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30750",
          "remediable": true
        },
        {
          "provider": "Twilio",
          "code": "30751",
          "remediable": true
        },
        {
          "provider": "Twilio",
          "code": "30752",
          "remediable": true
        }
      ],
      "applicability": {
        "entityTypes": [
          "SOLE_PROPRIETOR"
        ]
      },
      "applicabilityText": "Applies when the brand is a sole proprietor.",
      "universal": false,
      "remediation": "Use a personal mobile number that can receive the verification text, is not issued by a CPaaS provider, and has not already backed three registrations. The owner must reply YES within 24 hours.",
      "notes": "Off-platform: the reuse count and the CPaaS origin of a number both live in TCR, which we cannot query, so this rule can only ever warn. The user has to confirm for themselves that the number is a real personal handset and has not already backed three brands, and then be holding it when the OTP arrives — the 24-hour window starts at submission and cannot be restarted without a new registration.",
      "catalogIds": [
        "BRD-071"
      ],
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Is the verification number a personal handset the owner will have with them, not issued by a messaging provider, and used on fewer than three brands already?",
        "howToCheck": [
          "Confirm the number is on a consumer mobile carrier — not one bought from Twilio, Telnyx, Bandwidth or any messaging platform, including the console you are registering in.",
          "Ask the owner how many sole proprietor brands they have registered on this number. Three is the ceiling across the whole registry.",
          "Make sure the owner is expecting the verification text and can reply YES within 24 hours of submission."
        ],
        "failureLooksLike": "The number was provisioned in the same console being used to register, so it verifies as CPaaS-issued and is refused; or it is a fourth registration, which fails against a count nobody outside TCR can see."
      }
    },
    {
      "id": "BRD-075",
      "slug": "brd-075",
      "title": "The verification text must be answered within 24 hours",
      "statement": "The sole-proprietor OTP must be answered YES within 24 hours, or the verification must be re-triggered.",
      "rationale": "The window is short and it starts at submission, not when someone gets round to looking. A brand whose OTP expires does not fail loudly — it sits UNVERIFIED, and every campaign under it is refused for a reason that names the campaign rather than the unanswered text from yesterday. Registrations filed on a Friday afternoon are the classic version.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "sole-proprietor OTP state",
      "severity": "BLOCKING",
      "detectability": [
        "UNDETECTABLE_PRE_SUBMISSION"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "TCR",
        "Twilio",
        "Telnyx"
      ],
      "codes": [
        {
          "provider": "TCR",
          "code": "552",
          "remediable": true
        },
        {
          "provider": "Twilio",
          "code": "30752",
          "remediable": true
        }
      ],
      "applicability": {
        "entityTypes": [
          "SOLE_PROPRIETOR"
        ]
      },
      "applicabilityText": "Applies when the brand is a sole proprietor.",
      "universal": false,
      "remediation": "Submit the registration while the owner is at their phone, and tell them a text is coming that needs a YES. If the window has already passed, re-trigger the OTP from the brand record rather than creating a second brand — a duplicate registration burns one of the three uses this number is allowed.",
      "notes": "Nothing on our side can see whether the text was answered. The user has to watch for it: the message arrives within a minute or two of submission, the reply must be exactly YES, and after 24 hours the only route is to re-trigger — which is a button on the existing brand, not a resubmission.",
      "catalogIds": [
        "OPS-314"
      ],
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Will the number's owner be at their phone when you submit, and do they know to reply YES?",
        "howToCheck": [
          "Tell the owner before you submit: a text arrives within a minute or two, and the reply must be exactly YES.",
          "Submit while they are available — not on a Friday afternoon. The 24-hour window starts at submission, not when someone gets round to looking.",
          "If the window has passed, re-trigger the OTP from the existing brand. Do not create a second brand: that burns one of the three uses this number is allowed."
        ],
        "failureLooksLike": "The text expires unanswered. Nothing fails loudly — the brand sits UNVERIFIED and every campaign under it is refused for a reason that names the campaign."
      }
    },
    {
      "id": "BRD-076",
      "slug": "brd-076",
      "title": "Changing the mobile number re-runs the verification",
      "statement": "Any change to the sole-proprietor mobile number reverts the brand to UNVERIFIED and requires the OTP to be run again.",
      "rationale": "The number is the identity, so replacing it is a new identity claim rather than a contact-details update — the status drops and campaigns under the brand stop being registrable until a fresh YES arrives. People change it for entirely ordinary reasons, usually because they switched phones or mistyped a digit, and nothing warns them that a verified brand is about to go back in the queue.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.mobile_phone",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "TCR"
      ],
      "applicability": {
        "entityTypes": [
          "SOLE_PROPRIETOR"
        ]
      },
      "applicabilityText": "Applies when the brand is a sole proprietor.",
      "universal": false,
      "remediation": "Make the change with the new handset in hand, and expect a fresh verification text immediately. Do not change the number while a campaign is being reviewed — the brand will drop to UNVERIFIED underneath it.",
      "notes": "We can see that the number is being changed; we cannot see whether the new OTP was answered, which is BRD-075. What the user has to do is treat this as a re-verification rather than an edit, and schedule it accordingly.",
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Is the new handset in the owner's hand right now, and is there no campaign under review?",
        "howToCheck": [
          "Treat this as a re-verification rather than a contact-details edit: the brand drops to UNVERIFIED the moment the number changes.",
          "Make the change with the owner present, expect the verification text immediately, and check no campaign is mid-review — it will be judged against an unverified brand."
        ],
        "failureLooksLike": "A digit is corrected on a verified brand mid-week. The status drops, campaign registration stops, and nothing warned that a working brand was going back into the queue."
      }
    },
    {
      "id": "BRD-081",
      "slug": "brd-081",
      "title": "A sole-proprietor brand cannot buy its way to more throughput",
      "statement": "External vetting, and the throughput increases vetting buys, are not available on a sole-proprietor brand.",
      "rationale": "Vetting works by confirming a business against commercial records, and this tier exists precisely for people who are not in those records — so the vet has nothing to verify and the order is refused rather than failed. It matters because the obvious response to a low throughput cap is to buy a vet, and here that spends a non-refundable fee on an operation that was never possible.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "external vet order",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "Twilio",
        "Vonage"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30715",
          "remediable": true
        },
        {
          "provider": "TCR",
          "code": "525",
          "remediable": true
        }
      ],
      "applicability": {
        "entityTypes": [
          "SOLE_PROPRIETOR"
        ]
      },
      "applicabilityText": "Applies when the brand is a sole proprietor.",
      "universal": false,
      "remediation": "Do not order a vet on this brand. If the throughput cap is the problem, the route up is an EIN and a standard brand, which can then be vetted — the tier change is the increase, and the vet only helps once you are on the other tier.",
      "example": "vetting: none on a sole-proprietor brand — the throughput increase comes from moving to a standard brand instead",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-082",
      "slug": "brd-082",
      "title": "RCS brand assets are not available on the sole-proprietor tier",
      "statement": "Logo and banner assets for RCS cannot be uploaded to a sole-proprietor brand.",
      "rationale": "RCS shows a verified sender card with the brand's own artwork, and that card is a trust signal underwritten by the verification behind it — which on this tier is a text message to a phone. The upload is refused rather than queued, so a business that built its RCS artwork first discovers the channel is closed to it after the design work is done.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.assets",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR"
      ],
      "codes": [
        {
          "provider": "TCR",
          "code": "592",
          "remediable": true
        }
      ],
      "applicability": {
        "entityTypes": [
          "SOLE_PROPRIETOR"
        ]
      },
      "applicabilityText": "Applies when the brand is a sole proprietor.",
      "universal": false,
      "remediation": "Remove the asset upload from this registration. If RCS is the goal, obtain an EIN and register a standard brand — RCS asset upload and the verified sender card both hang off the standard verification path.",
      "example": "brand assets: none on the sole-proprietor tier — SMS and MMS only",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-084",
      "slug": "brd-084",
      "title": "Sole proprietor is not supported by every provider",
      "statement": "Some providers refuse sole proprietor registrations outright, and one also refuses sole proprietor appeals.",
      "rationale": "Provider support for the sole proprietor tier genuinely differs: TCR, Twilio, Telnyx and Vonage support it while Bandwidth and Sakari refuse it, and Bandwidth also refuses sole proprietor appeals. Discovering this after collecting the customer's data wastes a non-refundable submission.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.entity_type",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Bandwidth",
        "Sinch"
      ],
      "applicability": {
        "entityTypes": [
          "SOLE_PROPRIETOR"
        ],
        "providers": [
          "BANDWIDTH",
          "SINCH"
        ]
      },
      "applicabilityText": "Applies when the brand is a sole proprietor, and the submission target is BANDWIDTH and SINCH.",
      "universal": false,
      "remediation": "This provider does not accept sole proprietor brands. Either register through a provider that supports the tier, or obtain an EIN and register as a standard brand.",
      "notes": "PROVIDER-SPECIFIC — a genuine divergence, not a strictness difference. TCR, Twilio, Telnyx and Vonage all support the tier; Bandwidth and Sakari/Sinch refuse it. Tagged so it only fires when we know the target.",
      "catalogIds": [
        "OPS-340"
      ],
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Have you confirmed that the provider you are submitting through accepts sole proprietor brands at all?",
        "howToCheck": [
          "Read the provider's own 10DLC onboarding documentation for the sole proprietor or low-volume tier.",
          "Where it is not stated either way, ask support in writing before you collect the customer's personal details. Bandwidth and Sinch refuse the tier outright, and Bandwidth also refuses sole proprietor appeals."
        ],
        "failureLooksLike": "The API accepts the registration and it is refused downstream with a generic error, after a private individual's mobile number and home address have already been collected."
      }
    },
    {
      "id": "BRD-086",
      "slug": "brd-086",
      "title": "Sole-proprietor throughput is capped, and the CSP enforces it",
      "statement": "Sole-proprietor traffic is capped at roughly 1,000 messages a day and 15 a minute, enforced at the CSP rather than by the carrier.",
      "rationale": "Because the cap is applied upstream of the carrier, exceeding it does not produce message-level rejections — traffic is throttled or the account is reviewed, which looks like a delivery problem rather than a limit. A business planning a launch send on this tier will not find the ceiling in any error code, only in queue times that get steadily worse.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "sole-proprietor send rate",
      "severity": "HIGH",
      "detectability": [
        "UNDETECTABLE_PRE_SUBMISSION"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "TCR",
        "T-Mobile",
        "AT&T"
      ],
      "applicability": {
        "entityTypes": [
          "SOLE_PROPRIETOR"
        ]
      },
      "applicabilityText": "Applies when the brand is a sole proprietor.",
      "universal": false,
      "remediation": "Size the programme against roughly 1,000 messages a day and 15 a minute before committing to a schedule. If a single send would exceed it, spread it across days or move to a standard brand — there is no increase available on this tier.",
      "notes": "Send rate is not visible at registration time. The user has to do the arithmetic themselves — list size against the daily cap — and knowing that the CSP applies it means the symptom to watch for is throttling, not rejections.",
      "catalogIds": [
        "OPS-125"
      ],
      "phase": "post",
      "automated": false,
      "attestation": {
        "question": "Does your largest planned send fit inside roughly 1,000 messages a day and 15 a minute?",
        "howToCheck": [
          "Do the arithmetic before committing to a schedule: list size against the daily cap, and burst rate against 15 a minute.",
          "If a single send would exceed it, spread it across days or move to a standard brand. There is no increase available on this tier.",
          "Watch for throttling rather than rejections — the cap is applied at the CSP, upstream of the carrier."
        ],
        "failureLooksLike": "No error code names the ceiling. Queue times get steadily worse, the launch send arrives over two days, and it reads as a delivery problem rather than a limit."
      }
    },
    {
      "id": "BRD-087",
      "slug": "brd-087",
      "title": "Monthly sole-proprietor traffic reports are due by the 7th",
      "statement": "Where a CSP is enabled for sole-proprietor brands, monthly traffic reports must reach TCR by the 7th of the following month.",
      "rationale": "The tier was granted to CSPs on condition that its traffic is reported, so the filing is what keeps the tier available rather than a formality — a CSP that stops filing puts every sole-proprietor brand it holds at risk, not just its own standing. Businesses on the tier never see this obligation, which is exactly why it is worth their CSP knowing it exists.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "sole-proprietor traffic report",
      "severity": "HIGH",
      "detectability": [
        "HUMAN",
        "UNDETECTABLE_PRE_SUBMISSION"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "TCR"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Put the filing on a recurring calendar entry for the first working days of each month, with the previous month's sole-proprietor volumes. Done when the report is accepted by TCR before the 7th.",
      "notes": "An obligation on the CSP rather than on the brand, and nothing in a registration reveals whether it is being met. What the user has to establish is whether their provider is SP-enabled and files these reports — a provider that quietly stops can lose the tier, and every sole-proprietor brand behind it goes with it.",
      "catalogIds": [
        "OPS-317"
      ],
      "phase": "post",
      "automated": false,
      "attestation": {
        "question": "Is your provider enabled for sole-proprietor brands, and does it file the monthly traffic report to TCR by the 7th?",
        "howToCheck": [
          "Ask the provider directly whether they are SP-enabled and who owns the monthly filing.",
          "If you are the CSP, put the filing on a recurring calendar entry for the first working days of each month."
        ],
        "failureLooksLike": "A provider quietly stops filing and loses the tier. Every sole-proprietor brand behind it goes too, and none of those businesses ever knew the obligation existed."
      }
    },
    {
      "id": "BRD-090",
      "slug": "brd-090",
      "title": "A sole-proprietor brand cannot move between providers",
      "statement": "Sole-proprietor brands cannot be migrated from one CSP to another.",
      "rationale": "Migration carries a brand's verified status across, and on this tier that status is a verification of a person that the receiving CSP did not perform — so the path simply does not exist. Anyone changing provider has to re-register and answer a fresh OTP, which is survivable if it is planned and disruptive if it is discovered during the switch.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand migration request",
      "severity": "MEDIUM",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "TCR"
      ],
      "applicability": {
        "entityTypes": [
          "SOLE_PROPRIETOR"
        ]
      },
      "applicabilityText": "Applies when the brand is a sole proprietor.",
      "universal": false,
      "remediation": "Plan a provider change as a new registration: a new brand, a new campaign, and a fresh verification text to the same handset. Keep the old brand running until the new one is verified, and expect the number reuse to count against the three-registration limit.",
      "notes": "The migration is refused at the registry, not by us. What the user has to do is sequence the change themselves — stand the new brand up before retiring the old one — because there is no transfer to fall back on if the new registration stalls.",
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "If you are changing provider, have you planned this as a fresh registration rather than a transfer?",
        "howToCheck": [
          "Confirm there is no migration path for this tier — there is not — and plan a new brand, a new campaign and a fresh OTP to the same handset.",
          "Stand the new brand up before retiring the old one, and count the number reuse against the three-registration limit."
        ],
        "failureLooksLike": "The switch is planned as a migration, the request is refused at the registry mid-move, and there is no transfer to fall back on while the new registration stalls."
      }
    },
    {
      "id": "BRD-091",
      "slug": "brd-091",
      "title": "A complete physical business address is required",
      "statement": "Street, city, state or region, postal code and a two-letter country must all be populated.",
      "rationale": "The address is matched component by component against the registration record, so a missing component is not a partial match — it is a failed one. Half-filled addresses come from integrations that map a single free-text address string into the first field and leave the rest empty.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.street + city + state + postal_code + country",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "AWS",
        "TCR",
        "Bandwidth"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Populate all five components separately, matching the address on your IRS letter or business registration. Done when each field holds its own value rather than one field holding the whole address.",
      "example": "street: 1240 Mission St, Suite 400 · city: San Francisco · state: CA · postal_code: 94103 · country: US",
      "pitfalls": [
        "Where the registered address carries a suite number, omitting it is a component mismatch even though the post would arrive."
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-092",
      "slug": "brd-092",
      "title": "US and Canadian addresses use the two-letter state code",
      "statement": "For a US or Canadian address, the state or province must be the two-letter abbreviation.",
      "rationale": "The address match is a string comparison against a record that holds the abbreviation, so \"California\" and \"CA\" are simply different values and the address fails to validate. It is the most common single-component address rejection, and the least obvious, because the address is otherwise perfectly correct.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.state",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "AWS",
        "TCR",
        "Bandwidth"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Replace the full name with the two-letter USPS or Canada Post abbreviation, in upper case. Done when the field holds exactly two letters.",
      "example": "state: CA — not California, not Calif.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-093",
      "slug": "brd-093",
      "title": "The address must match the registration record component by component",
      "statement": "The registered address must match the address on the IRS or national registration record exactly, including abbreviation style.",
      "rationale": "The address is compared as a set of strings rather than resolved as a place, so \"1240 Mission Street\" against a record holding \"1240 Mission St\" is a failed component and therefore a failed address. Every business writes its own address the way it looks best on a letterhead, and the registration record was typed once, years ago, by somebody else.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.street … brand.postal_code",
      "severity": "BLOCKING",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Telnyx",
        "TCR",
        "HighLevel"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30795",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Copy the address from the IRS letter or the registry extract rather than from the website, keeping its abbreviations exactly — St or Street, Ste or Suite, whichever the record uses. Done when every component is character-identical to the record.",
      "notes": "Absorbs BRD-094, which states how the comparison is made rather than a separate requirement. We hold no registration record to compare against, so this is the one check the user has to run by eye: put the letter next to the form and read the two addresses line by line, including the abbreviations, before submitting.",
      "catalogIds": [
        "BRD-094"
      ],
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Is every component of the address character-identical to the address on the IRS letter or registry extract, abbreviations included?",
        "howToCheck": [
          "Put the letter next to the form and read the two addresses line by line — this is the one check that has to be done by eye.",
          "Match the record's abbreviation style exactly: St or Street, Ste or Suite, whichever it uses.",
          "Copy from the letter, never from the website — the website is written to look good on a letterhead."
        ],
        "failureLooksLike": "\"1240 Mission Street\" against a record holding \"1240 Mission St\". One failed component is a failed address; the comparison never resolves it as a place."
      }
    },
    {
      "id": "BRD-095",
      "slug": "brd-095",
      "title": "The address must validate as deliverable",
      "statement": "House number, street, locality and postal code must all resolve to a deliverable address at the postal authority.",
      "rationale": "Providers run the address through USPS or Canada Post and reject each component separately, so the rejection arrives as \"Invalid Locality\" or \"Invalid House Number\" — precise, and useless to someone who can see the mail arriving at that address every day. The usual cause is a suite number in the street line where the validator wants it as a secondary component, or a locality that is the neighbourhood rather than the post town.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.street … brand.postal_code",
      "severity": "BLOCKING",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Twilio",
        "Sinch",
        "Infobip"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30754",
          "remediable": true
        },
        {
          "provider": "Sinch",
          "code": "CR2002",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Run the address through the USPS ZIP Code lookup before submitting and use the standardised form it returns, including its abbreviations and its ZIP+4. Done when the postal authority returns exactly the address you are about to submit.",
      "notes": "We do not query the postal authority. The user has to do this themselves, and the USPS lookup is the fastest route: it returns the canonical form, which is also the form BRD-093 wants compared against the registration record.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Does the postal authority return exactly the address you are about to submit?",
        "howToCheck": [
          "Run the address through the USPS ZIP Code lookup (or Canada Post) and use the standardised form it returns, including its abbreviations and ZIP+4.",
          "Watch two specific components: a suite number sitting in the street line when the validator wants it separately, and a locality that is the neighbourhood rather than the post town."
        ],
        "failureLooksLike": "The rejection reads \"Invalid Locality\" or \"Invalid House Number\" — precise, and useless to someone who watches the mail arrive at that address every day."
      }
    },
    {
      "id": "BRD-096",
      "slug": "brd-096",
      "title": "Brand address must be a physical address, not a PO box",
      "statement": "The registered business address must be a street address; PO boxes are rejected.",
      "rationale": "The registered address is meant to locate a real operating business, and a PO box locates a mailbox. It is a cheap, mechanical check that providers apply consistently, so it rejects reliably.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.street",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Telnyx",
        "Sinch",
        "Infobip",
        "AWS"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Provide the physical street address where the business actually operates, including suite or unit number. If you work from home and prefer not to publish it, use a registered agent or coworking address that receives mail — but it must be a street address, not a PO box or mailbox service.",
      "example": "123 Market St, San Francisco, CA 94103",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-097",
      "slug": "brd-097",
      "title": "Include the suite or unit number the registry holds",
      "statement": "Where the registration record carries a suite, unit or apartment number, the brand address must carry it too.",
      "rationale": "A missing secondary component reads as a partial match, and partial matches lower the trust score rather than failing outright — so nothing is rejected and the brand quietly lands in a worse carrier class. Businesses omit it because the post arrives without it, which is true and irrelevant to a string comparison.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.street (secondary line)",
      "severity": "HIGH",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Quo"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Add the suite or unit exactly as the registration record writes it, in the same field as the street where the form has only one address line. Done when the brand address carries every component the record does.",
      "notes": "What the registry holds is not visible to us. The user has to check their own registration extract or IRS letter for a secondary component and reproduce it — including the abbreviation, since \"Suite 400\" and \"Ste 400\" are different strings to the comparison.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Does the registration record carry a suite, unit or apartment number — and if so, is it on the brand address too?",
        "howToCheck": [
          "Look for a secondary component on your registration extract or IRS letter. Post arriving without it proves nothing; the comparison is against the record, not the postman.",
          "Reproduce the abbreviation as the record writes it. \"Suite 400\" and \"Ste 400\" are different strings."
        ],
        "failureLooksLike": "Nothing is rejected. The partial match lowers the trust score, and the brand quietly lands in a worse carrier class with no finding to point at."
      }
    },
    {
      "id": "BRD-098",
      "slug": "brd-098",
      "title": "Register the company address, not the branch you work from",
      "statement": "A branch or local-office address must not be submitted where the official registered company address differs.",
      "rationale": "Whoever fills in the form gives the address they sit at, which for any business with more than one site is not the registered one. It is not rejected outright — it drags the trust score down, which is worse, because the brand verifies and then underperforms with no finding to point at.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.street",
      "severity": "HIGH",
      "detectability": [
        "HUMAN"
      ],
      "failureClass": "TERMINAL_EVIDENCE",
      "authorities": [
        "HighLevel"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Use the address on the company registration — the registered office or principal place of business — even where nobody sits there. Branch addresses belong on the website and in the campaign content, not on the brand record.",
      "notes": "Nothing on the form distinguishes a branch from a head office. The user has to establish which address their registration record holds and use that one, which usually means asking whoever files the company's returns rather than whoever is filling in this form.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Is the address on this brand the registered company address, rather than the office whoever filled in the form sits in?",
        "howToCheck": [
          "Ask whoever files the company's returns which address the registration record holds — the registered office or principal place of business.",
          "Use that one even if nobody sits there. Branch addresses belong on the website and in campaign content, not on the brand record."
        ],
        "failureLooksLike": "A regional office address is submitted because that is where the person filling in the form works. The brand verifies and then underperforms, with the score drag and no finding to explain it."
      }
    },
    {
      "id": "BRD-099",
      "slug": "brd-099",
      "title": "The address is checked against spam and scam complaint data",
      "statement": "The registration address must not appear in known spam or scam complaint data.",
      "rationale": "Fraudulent registrations cluster at a small number of addresses — virtual offices, mail forwarders, addresses reused across dozens of shell brands — so the address itself is screened against complaint intelligence. A legitimate business at a shared or virtual office can inherit that history without ever knowing about it, and the rejection gives no reason a business could act on.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.street",
      "severity": "BLOCKING",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Sinch"
      ],
      "codes": [
        {
          "provider": "Sinch",
          "code": "CR2023",
          "remediable": false
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Where a rejection points at the address, move the registration to the physical premises the business actually occupies rather than to a registered-agent or virtual-office address. Where the business genuinely has no other address, expect to appeal with evidence of occupancy — a lease or a utility bill.",
      "notes": "Threat-intelligence data we do not hold. The user cannot check this in advance; what they can do is avoid the pattern that triggers it, which is registering at a mail-forwarding or virtual-office address shared with unrelated brands.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Is this the physical premises the business occupies, rather than a virtual office, mail forwarder or registered-agent address?",
        "howToCheck": [
          "Establish what kind of address this is. Fraudulent registrations cluster at addresses shared across dozens of unrelated shell brands, and the screening is against that history rather than against you.",
          "Where the business genuinely has no other address, have evidence of occupancy ready for an appeal — a lease or a utility bill."
        ],
        "failureLooksLike": "A legitimate business at a shared virtual office inherits a complaint history it never knew about, and the rejection gives no reason it could act on."
      }
    },
    {
      "id": "BRD-101",
      "slug": "brd-101",
      "title": "Express PIN delivery needs a real street address",
      "statement": "A PO box, mailbox service or general-delivery address cannot be used when express PIN delivery is requested for political vetting.",
      "rationale": "Political vetting confirms identity by couriering a PIN to the registered address, and couriers do not deliver to a PO box or a mailbox service — so the vet is bought, the PIN is dispatched, and it comes back undelivered. The fee is spent either way, and the campaign schedule is the thing that actually suffers, because political programmes are usually dated.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.street",
      "severity": "HIGH",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR"
      ],
      "applicability": {
        "useCases": [
          "POLITICAL"
        ]
      },
      "applicabilityText": "Applies when the use case is POLITICAL.",
      "universal": false,
      "remediation": "Give a street address where a courier can hand the envelope to a person during business hours — the campaign office, not the treasurer's mailbox. Done when the address has a house number and a street and no box number.",
      "example": "street: 1240 Mission St, Suite 400 — not \"PMB 118, 1240 Mission St\" and not a UPS Store box",
      "pitfalls": [
        "A mailbox-service address looks like a street address by design: \"1240 Mission St #118\" is a street address, and \"PMB 118\" at the same building is not."
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-102",
      "slug": "brd-102",
      "title": "A brand support phone number is required",
      "statement": "Every brand must supply a support phone number.",
      "rationale": "The support number is what a carrier investigating a complaint, and a consumer answering HELP, are given as the route to a person. A brand with no number reachable behind it is exactly the shape of the traffic 10DLC exists to filter, so its absence weighs more than the effort of supplying it suggests.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.phone",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "AWS",
        "Bandwidth"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Supply a number that reaches your business during business hours, and use the same one in your HELP auto-reply. Done when the field is populated and the number answers.",
      "example": "phone: +14155550134",
      "pitfalls": [
        "A number that rings to an unmonitored voicemail satisfies the field and fails the check a reviewer actually runs, which is to call it."
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-103",
      "slug": "brd-103",
      "title": "The support phone must be in E.164",
      "statement": "The brand support phone must be submitted in E.164: a leading plus, the country code, and digits with no separators.",
      "rationale": "E.164 is the only form the registry parses unambiguously — a number with dashes or brackets is either rejected outright or silently truncated, and a truncated support number is worse than a missing one because nothing flags it. Forms that display a friendly format and submit what was displayed are the usual cause.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.phone",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "AWS",
        "Telnyx"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Strip the spaces, dashes, dots and brackets, and prefix the country code with a plus. A US number becomes +1 followed by ten digits. Done when the value matches +[country code][digits] with nothing else in it.",
      "example": "phone: +14155550134 — not 415-555-0134 and not (415) 555-0134",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-104",
      "slug": "brd-104",
      "title": "The support phone must reach the business",
      "statement": "The brand support number must route to the business and be answerable during business hours.",
      "rationale": "Reviewers call it. That is the whole check: a number that rings out, reaches a personal voicemail, or lands on a disconnected line tells them the business either does not exist or cannot be contacted, and both readings end the same way. Businesses supply the owner's mobile or a line that was reassigned during an office move, and never learn that the number was the finding.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.phone",
      "severity": "HIGH",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Klaviyo",
        "Telnyx"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Use the number published on the business website, and make sure it is answered — by a person or by a greeting that names the business — during ordinary business hours. Done when calling it yourself from an unknown number reaches the business by name.",
      "notes": "We cannot dial it. What the user has to do is exactly what the reviewer will: call the number from a phone the business does not recognise, in business hours, and listen to what a stranger hears.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "When you call this number from a phone the business does not recognise, during business hours, does a person or a greeting name the business?",
        "howToCheck": [
          "Do exactly what the reviewer will do: dial it yourself, in business hours, from an unknown number, and listen to what a stranger hears.",
          "Use the number published on the business website, not the owner's mobile — and check it was not reassigned during an office move."
        ],
        "failureLooksLike": "It rings out, or reaches a personal voicemail with no business name. The reviewer reads that as a business that either does not exist or cannot be contacted, and never tells you the number was the finding."
      }
    },
    {
      "id": "BRD-106",
      "slug": "brd-106",
      "title": "The business phone should be findable in a web search",
      "statement": "The registered business phone number should be discoverable through a public web search for the business.",
      "rationale": "Corroboration is how a vetting provider raises a score it cannot otherwise justify: a number that appears on the business's own site, in directories and on listings ties the registration to a business with a history. A brand-new number that appears nowhere is not wrong, it is simply unsupported, and the score reflects that without ever saying so.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.phone",
      "severity": "MEDIUM",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Telnyx"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Publish the same number on the website contact page and in the business's main directory listings before registering, and use that number on the brand. Done when searching the business name and the number together returns the business.",
      "notes": "An open-web search we do not run. The user should do it themselves before submitting — search the business name and see whether this number comes back — because a number that is new everywhere is worth publishing for a week before the registration rather than after it.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Does searching the business name and this phone number together return the business?",
        "howToCheck": [
          "Run the search yourself before submitting.",
          "If the number appears nowhere, publish it on the website contact page and the main directory listings and give it a week before registering — corroboration is what lets a vetting provider raise a score it otherwise cannot justify."
        ],
        "failureLooksLike": "A brand-new number is not wrong, it is unsupported. The score reflects that and never says so."
      }
    },
    {
      "id": "BRD-107",
      "slug": "brd-107",
      "title": "The representative's phone number may back only one brand",
      "statement": "An authorised representative's phone number already used on another brand cannot be used again.",
      "rationale": "Reusing a contact number across brands is the signature of one operator registering many businesses, which is the pattern brand-level accountability exists to prevent. Agencies trip it honestly by putting their own account manager on every client brand, and the collision is reported against the newest registration rather than against the practice.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.authorized_rep.phone",
      "severity": "BLOCKING",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Twilio",
        "TCR"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30703",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Name a representative who works for the business being registered and use their number. Your own staff belong on the CSP record, which is where a platform's contact details are supposed to live.",
      "notes": "The collision is against every brand in the registry, which we cannot see. What the user has to do is use a different, genuine representative per brand — and if an agency has already spread one number across several brands, expect the next registration to be the one that is refused rather than the earlier ones.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Is the representative on this brand an employee of the business being registered, with a number used on no other brand?",
        "howToCheck": [
          "Check who is named. An agency account manager on every client brand is the usual cause, and it is reported against the newest registration rather than against the practice.",
          "Your own staff belong on the CSP record, which is where a platform's contact details are meant to live."
        ],
        "failureLooksLike": "One number spread across six client brands. The seventh registration is refused for a collision the earlier six caused."
      }
    },
    {
      "id": "BRD-108",
      "slug": "brd-108",
      "title": "The brand support email must be well formed",
      "statement": "The brand support email must be a syntactically valid address.",
      "rationale": "A malformed address fails at the API boundary, and where it does not, it silently swallows the 2FA and verification mail the brand is waiting on — so the registration stalls with no visible cause. Trailing spaces and a missing top-level domain are the two shapes that survive a form's own validation.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.email",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "AWS"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Correct the address so it has a local part, an @, and a domain with a dot in it. Done when a test message to it arrives — the verification mail will go to this address.",
      "example": "email: support@acmecoffee.com",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-109",
      "slug": "brd-109",
      "title": "Brand contact email must not use a free consumer domain",
      "statement": "The brand support/business contact email must be on a domain the business controls, not a free consumer mail provider.",
      "rationale": "A business-domain email is weak evidence that the registrant controls the business they are registering. Free consumer addresses are the pattern fraudulent registrations use, so several providers reject them outright rather than weighting them.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.email",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "AWS",
        "TCR",
        "Sinch",
        "Bandwidth",
        "Telnyx"
      ],
      "applicability": {
        "excludeEntityTypes": [
          "SOLE_PROPRIETOR"
        ]
      },
      "applicabilityText": "Applies when the brand is NOT a sole proprietor.",
      "universal": false,
      "remediation": "Use an email address on your business domain (e.g. support@yourcompany.com). Free consumer addresses are rejected for registered entities.",
      "example": "support@acmecoffee.com",
      "notes": "Sole proprietors are carved out — they legitimately have no business domain. Severity varies by authority (MEDIUM at carriers, BLOCKING at AWS/TCR/Sinch); strictest kept.",
      "catalogIds": [
        "BRD-110"
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-111",
      "slug": "brd-111",
      "title": "The contact email domain must be provably the brand's",
      "statement": "The brand contact email must be on a domain the business demonstrably owns — shown on its website, matching WHOIS, or verified by DNS.",
      "rationale": "Authentication+ sends a PIN to this mailbox and treats whoever answers it as the business, so domain ownership is the thing being verified rather than a formality about tidy addresses. A domain that appears nowhere on the brand's own site cannot be tied back to it, and the verification is refused rather than delayed.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.business_contact_email domain",
      "severity": "BLOCKING",
      "detectability": [
        "CRAWL",
        "EXTERNAL_DATA"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Twilio",
        "TCR"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "21736",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Use a mailbox on the same domain as the registered website, and make sure that domain appears as a contact address somewhere on the site. Where the business uses a different mail domain, publish it on the site's contact page before submitting. Done when the domain in the email can be found on the brand's own website.",
      "example": "business_contact_email: jane.doe@acmecoffee.com · website: https://acmecoffee.com",
      "notes": "Absorbs BRD-118, which is the same ownership requirement stated for the Auth+ flow. Recommended universally and mandatory for public companies. The crawl can tell us whether the domain appears on the site; WHOIS and DNS TXT verification are external, so where the site does not show the address the user has to establish ownership another way — usually by publishing it on the contact page, which is also the cheapest fix.",
      "catalogIds": [
        "BRD-118"
      ],
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Can the email domain on this brand be found on the brand's own website?",
        "howToCheck": [
          "Open the registered website and look for an address on this domain — the contact page is where a reviewer looks.",
          "Where the business uses a different mail domain from its website, publish it on the contact page before submitting. That is the cheapest way to establish ownership.",
          "Authentication+ sends a PIN to this mailbox and treats whoever answers it as the business, so the domain is the thing being verified."
        ],
        "failureLooksLike": "A mail domain that appears nowhere on the site cannot be tied back to the business, and the verification is refused rather than delayed."
      }
    },
    {
      "id": "BRD-112",
      "slug": "brd-112",
      "title": "Brand contact email must not be a role or distribution address",
      "statement": "The brand business-contact email must be an individual mailbox, not a role or group address such as info@ or sales@.",
      "rationale": "The contact address receives the Authentication+ verification PIN, and a shared inbox either loses it or is not monitored inside the short expiry window. Several providers reject role addresses outright for that reason, which surprises brands who deliberately used a \"professional\" address.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.email",
      "severity": "HIGH",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "AWS",
        "Twilio"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Use a named individual mailbox on the business domain that someone actually monitors — the verification PIN expires quickly and cannot be resent indefinitely.",
      "example": "jane.doe@acmecoffee.com rather than info@acmecoffee.com",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-114",
      "slug": "brd-114",
      "title": "Disposable mailboxes are refused outright",
      "statement": "The brand contact email must not be on a disposable or temporary mail domain.",
      "rationale": "A throwaway address means nobody can be reached at the business tomorrow, which defeats the point of collecting a contact at all — and every verification message, PIN and carrier enquiry goes to it. It is refused rather than scored down, and it reaches the field honestly during testing, when somebody wanted a working address without using their own.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.email",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC",
        "EXTERNAL_DATA"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Twilio",
        "TCR",
        "Vonage"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30753",
          "remediable": true
        },
        {
          "provider": "Twilio",
          "code": "30701",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Use a monitored mailbox on the business domain. If you are testing, register a mock brand (BRD-204) rather than a real one with a temporary address. Done when the address will still receive mail in six months.",
      "example": "email: support@acmecoffee.com — not a mailinator.com or 10minutemail.com address",
      "notes": "Absorbs BRD-079, which states the same requirement for sole-proprietor brands. The check carries the well-known disposable providers; the full list is maintained externally and changes constantly, so a domain passing here is not proof it is off the provider's list — the user still has to use a mailbox the business genuinely keeps.",
      "catalogIds": [
        "BRD-079"
      ],
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Will this mailbox still receive mail in six months, and is it monitored by someone at the business?",
        "howToCheck": [
          "Confirm the domain is the business's own, not a temporary or disposable mail service. The provider's blocklist is maintained externally and changes constantly, so passing our check is not proof it is off theirs.",
          "Testing rather than registering? Use a mock brand instead of a real one with a throwaway address."
        ],
        "failureLooksLike": "A temporary address entered during testing reaches production. Every verification message, PIN and carrier enquiry goes to a mailbox that no longer exists, and the brand is refused rather than scored down."
      }
    },
    {
      "id": "BRD-115",
      "slug": "brd-115",
      "title": "The email domain must resolve",
      "statement": "The brand contact email domain must resolve with an MX or A record.",
      "rationale": "A domain with no mail records cannot receive the verification message, so the registration stalls waiting for a reply that could never arrive. It happens to businesses that registered a domain for the website and never configured mail on it, and to anyone who mistypes a domain into an address that otherwise looks perfect.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.email domain",
      "severity": "BLOCKING",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Twilio",
        "TCR"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30701",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Send a test message to the address from an outside account and confirm it arrives. If it bounces, the domain has no mail service — use a domain that does, or configure mail on this one before registering.",
      "notes": "A DNS lookup we do not perform. The user's equivalent is the test message: sending one from a personal account settles both the MX record and the mailbox in a single step, which is worth doing before the registration rather than after it stalls.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Did a test message sent from an outside account actually land in this mailbox?",
        "howToCheck": [
          "Send one message from a personal account and confirm it arrives. That settles the MX record and the mailbox in a single step.",
          "If it bounces, the domain has no mail service — use a domain that does, or configure mail on this one before registering."
        ],
        "failureLooksLike": "A domain registered for the website with mail never configured. The registration stalls waiting for a reply to a message that could never have arrived."
      }
    },
    {
      "id": "BRD-117",
      "slug": "brd-117",
      "title": "A public company must supply a business contact email",
      "statement": "A PUBLIC_PROFIT brand must carry a business contact email — it is mandatory and it triggers the Authentication+ 2FA.",
      "rationale": "For a public company this field is not a contact detail, it is the second factor: the PIN goes to it and the brand cannot reach VERIFIED without one. Omitting it does not produce a missing-field error people recognise — the brand sits in an authentication-required state, which reads as a queue rather than as a blank box.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.business_contact_email",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "AWS",
        "Telnyx"
      ],
      "codes": [
        {
          "provider": "TCR",
          "code": "501",
          "remediable": true
        },
        {
          "provider": "Twilio",
          "code": "30994",
          "remediable": true
        }
      ],
      "applicability": {
        "entityTypes": [
          "PUBLIC_PROFIT"
        ]
      },
      "applicabilityText": "Applies when the brand is a public company.",
      "universal": false,
      "remediation": "Supply a named individual's mailbox on the company domain, monitored by someone who will act on a verification mail within days. Done when the field is populated and that person knows a PIN is coming.",
      "example": "business_contact_email: jane.doe@acmecoffee.com — an individual mailbox on the company domain",
      "pitfalls": [
        "The PIN expires (BRD-227), so an address that is technically valid but monitored monthly fails the verification just as surely as an empty field."
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-119",
      "slug": "brd-119",
      "title": "Confirm the mailbox accepts outside mail before triggering 2FA",
      "statement": "The brand contact mailbox must be able to receive external mail before Authentication+ 2FA is triggered.",
      "rationale": "Corporate mail filters reject or quarantine unfamiliar senders, and a verification mail that is silently dropped looks identical to one that was never sent — the brand waits in an authentication-required state and nobody knows why. Larger companies, which are exactly the ones registering as public, have the strictest filters.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.business_contact_email deliverability",
      "severity": "HIGH",
      "detectability": [
        "UNDETECTABLE_PRE_SUBMISSION"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Twilio"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "21738",
          "remediable": true
        }
      ],
      "applicability": {
        "entityTypes": [
          "PUBLIC_PROFIT"
        ]
      },
      "applicabilityText": "Applies when the brand is a public company.",
      "universal": false,
      "remediation": "Send a test message from an outside domain to this mailbox and confirm it lands in the inbox rather than in quarantine. Where IT filters unknown senders, have the provider's sending domain allow-listed before the vet is ordered.",
      "notes": "Deliverability is only observable after the mail is sent. What the user has to do is test it first — one message from a personal account — and, in a filtered environment, get the verification sender allow-listed before ordering the vet, because the 30-day window (BRD-226) runs whether or not the mail arrived.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Has a test message from an outside domain reached this mailbox's inbox, rather than its quarantine?",
        "howToCheck": [
          "Send the test from a personal account and have the contact confirm it landed in the inbox — not in a junk folder or a quarantine digest.",
          "In a filtered corporate environment, get the provider's sending domain allow-listed by IT before the vet is ordered.",
          "The 30-day vet window runs whether or not the mail arrived, so do this first."
        ],
        "failureLooksLike": "A silently quarantined verification mail is indistinguishable from one that was never sent. The brand waits in an authentication-required state and nobody knows why."
      }
    },
    {
      "id": "BRD-120",
      "slug": "brd-120",
      "title": "Changing a public brand's contact email resets its identity",
      "statement": "Any change to a PUBLIC_PROFIT brand's business contact email resets identity verification and requires the 2FA to be completed again.",
      "rationale": "The mailbox is the second factor, so replacing it replaces the evidence the verification rests on — the brand drops out of VERIFIED and the Authentication+ state goes with it. Teams make this change for entirely routine reasons, usually when the named person leaves, and discover the brand is unverified only when the next campaign is refused.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.business_contact_email",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "TCR",
        "Twilio"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30994",
          "remediable": true
        }
      ],
      "applicability": {
        "entityTypes": [
          "PUBLIC_PROFIT"
        ]
      },
      "applicabilityText": "Applies when the brand is a public company.",
      "universal": false,
      "remediation": "Plan the change: the new contact must be available to answer a PIN within days of the edit, and campaign registration is blocked until they do. Where the change is only a departing employee, prefer a role-independent mailbox on the same domain that a person actually monitors.",
      "notes": "The reset happens at the registry once the change is submitted. What the user has to do is sequence it — make the change when the new contact is at their desk, not during their holiday — because the brand is unverified for the whole gap, and every campaign under it is refused meanwhile.",
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Will the new contact be at their desk and able to answer a PIN within days of this change?",
        "howToCheck": [
          "Sequence the edit around the person: make it when the new contact is available, not the day before their holiday.",
          "Expect the brand to leave VERIFIED and campaign registration to be blocked for the whole gap.",
          "Where the change is only a departing employee, prefer a role mailbox on the same domain that a named person actually monitors."
        ],
        "failureLooksLike": "The contact is updated routinely when someone leaves. The brand is silently unverified, and the team finds out when the next campaign is refused."
      }
    },
    {
      "id": "BRD-121",
      "slug": "brd-121",
      "title": "The support contact must be the end customer's, not the agency's",
      "statement": "The brand contact email must reach the business being registered, not the ISV, agency or reseller that filed the registration.",
      "rationale": "The contact address is where a carrier investigation and a consumer complaint land, so an agency address puts a middleman between the regulator and the business that owns the consent. It also drives a specific failure the agency never sees: the verification mail goes to the agency, the customer never learns their brand needs action, and the registration stalls while both sides wait for the other.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.email vs the registering tenant",
      "severity": "HIGH",
      "detectability": [
        "AI_FORM"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Twilio"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30881",
          "remediable": true
        },
        {
          "provider": "Twilio",
          "code": "30894",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Put the end customer's own support mailbox in the brand email field — the one printed on their website. Your own address belongs on the CSP or reseller record, where it will still receive the API notifications. Done when the brand email is on the customer's domain.",
      "example": "brand email: support@acmecoffee.com — not support@northstarplatform.io on a brand registered for Acme Coffee",
      "pitfalls": [
        "A shared mailbox you monitor on the customer's behalf still has to be on their domain. Forwarding is fine; the address is what is compared."
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-122",
      "slug": "brd-122",
      "title": "A well-known brand name on a consumer mail domain reads as impersonation",
      "statement": "A widely recognised company name paired with a free or non-corporate email domain must be treated as probable impersonation.",
      "rationale": "Impersonating a bank or a retailer is the highest-value use of a fraudulent brand, and the cheapest tell is that the registrant could not produce an address on the company's own domain. Reviewers act on that tell hard, which means a franchisee or a regional reseller using a personal address gets caught in the same net — the fix for them is a real corporate address, not an explanation.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.company_name + brand.email",
      "severity": "BLOCKING",
      "detectability": [
        "AI_FORM",
        "EXTERNAL_DATA"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "AWS",
        "Bandwidth"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Use an email address on the domain the named company actually operates. If you are a franchisee or an authorised reseller, register under your own legal entity name rather than the parent brand's, and use your own domain. Done when the name in the brand field and the domain in the email field belong to the same organisation.",
      "example": "company_name: Acme Coffee Co, LLC · email: support@acmecoffee.com — not acmecoffee@gmail.com",
      "pitfalls": [
        "Adding a location to the name — \"Acme Coffee Portland\" — does not resolve it while the email domain still belongs to nobody in particular."
      ],
      "notes": "Whether a name is a well-known brand, and whether this registrant is authorised to use it, both need data we do not hold. The user has to satisfy themselves that they can evidence the right to register under this name — a franchise agreement or a reseller authorisation — because a reviewer who suspects impersonation will ask for exactly that.",
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "If you are registering under a name a consumer would recognise, can you produce the document that authorises you to use it?",
        "howToCheck": [
          "Find the franchise agreement, reseller authorisation or letter of appointment that names your entity.",
          "Check the email domain on the brand belongs to the same organisation as the name in the brand field.",
          "No such document: register under your own legal entity name and your own domain instead."
        ],
        "failureLooksLike": "A national brand name paired with a gmail.com address. A reviewer reads that as impersonation and asks for the authorisation — and adding a city to the name does not help while the domain still belongs to nobody in particular."
      }
    },
    {
      "id": "BRD-125",
      "slug": "brd-125",
      "title": "The website URL must carry an explicit scheme",
      "statement": "The brand website must be submitted with an explicit http:// or https:// scheme.",
      "rationale": "A bare domain is not a URL, and the registry does not add a scheme for you — it rejects the field or stores something no crawler can fetch, which reads downstream as a brand with no website. Users type the domain because that is what they say when they tell someone their address.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.website",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "AWS",
        "Telnyx"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Prefix the domain with https://. Done when the value starts with https:// and opens in a browser exactly as submitted.",
      "example": "website: https://acmecoffee.com — not acmecoffee.com and not www.acmecoffee.com",
      "pitfalls": [
        "http:// is a scheme and still fails the separate https requirement, so add the s while you are there."
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-126",
      "slug": "brd-126",
      "title": "The brand website is the root domain, not a page inside it",
      "statement": "The brand website must be submitted as the root domain rather than a deep link or sub-path.",
      "rationale": "A reviewer given a specific page sees that page and nothing else, and a landing page or a product page rarely carries the business identity, the policy links or the contact details they are looking for. Registrants deep-link with the best intentions — usually to the signup page they are proudest of — and hand the reviewer the one view of the site that proves least.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.website",
      "severity": "MEDIUM",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Telnyx"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Put the site root in the brand website field. The opt-in page still gets cited — it belongs in the campaign message flow, where a deep link is exactly what is wanted. Done when the brand website is a bare domain with no path on it.",
      "example": "website: https://acmecoffee.com — with https://acmecoffee.com/checkout cited in the message flow instead",
      "notes": "The mirror of WEB-090, which asks the message flow to deep-link the opt-in page. The two fields want opposite things and for the same reason: the brand field proves the business exists, the flow field proves the consent surface does.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-132",
      "slug": "brd-132",
      "title": "The website domain must relate recognisably to the brand name",
      "statement": "The registered website's domain must bear a recognisable relationship to the legal name or the DBA.",
      "rationale": "A reviewer confirms a brand exists by opening its website, and a domain with no visible connection to the name gives them nothing to confirm — they cannot tell a rebrand from a borrowed site. Honest causes are everywhere: a company that acquired a better domain, a practice trading under a founder's name on a descriptive URL, a store on a platform subdomain.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.website vs brand.company_name / brand.dba",
      "severity": "HIGH",
      "detectability": [
        "AI_FORM",
        "CRAWL"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Twilio",
        "Bandwidth"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Register the domain the business actually trades under, and make sure that domain's home page names the business in its title or header. Where the domain genuinely differs from the name, add the trading name to the DBA field so the two can be connected. Done when a reviewer landing on the site can see the registered name on it.",
      "example": "company_name: Acme Coffee Co, LLC · website: https://acmecoffee.com",
      "pitfalls": [
        "A platform subdomain such as a myshopify.com store is the common version of this, and it fails for a second reason as well — it is not the brand's own domain."
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-135",
      "slug": "brd-135",
      "title": "A website may back only one brand",
      "statement": "A website URL already registered against another brand cannot be registered again.",
      "rationale": "The site is treated as an identity key, so two brands claiming the same one is read as one business registered twice — which is the thing per-brand accountability exists to prevent. Franchise groups and multi-location businesses hit it legitimately: every location wants its own brand, and they all share the corporate site.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.website",
      "severity": "BLOCKING",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Twilio",
        "TCR"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30703",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Give each brand its own web presence — a location page on its own subdomain, or the franchisee's own site — rather than pointing several brands at one corporate root. Where the same legal entity is behind both, register one brand and run several campaigns under it instead.",
      "notes": "The collision is registry-wide and invisible to us. What the user has to establish is whether anyone else — a franchisor, a former agency, another location — has already registered a brand against this URL, because the second registration is the one that is refused.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Has any other brand — a franchisor, another location, a former agency — already been registered against this website?",
        "howToCheck": [
          "Ask the franchisor or head office whether a brand already exists on the corporate URL.",
          "Where several locations need their own brands, give each its own web presence: a location page on its own subdomain, or the franchisee's own site.",
          "Where the same legal entity is behind both, register one brand and run several campaigns under it."
        ],
        "failureLooksLike": "Six locations point at one corporate root. The first registration works and every later one is refused, against a record the franchisee cannot see."
      }
    },
    {
      "id": "BRD-143",
      "slug": "brd-143",
      "title": "A brand with no website must attach its policy document",
      "statement": "Where the brand registers no website, a compliant policy document must be attached to the registration or hosted at a public URL.",
      "rationale": "Every consent and disclosure requirement assumes a page a reviewer can open. A business with no website is not disqualified — plenty of legitimate senders have none — but it has to supply the same content some other way, and nothing on the form says so. The registration is refused for missing policies that the business would happily have provided.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "policy attachment",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "TERMINAL_POLICY",
      "artifact": "privacy_policy",
      "authorities": [
        "Alive5",
        "BeeTexting"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Publish the privacy policy and the SMS terms at a public URL — a hosted document, a Google Doc set to public, or a one-page site — and cite them on the registration. Done when both documents open in a browser with no login and are reachable from the registration.",
      "example": "policy_document_url: https://cdn.acmecoffee.com/compliance/sms-privacy-policy.pdf — where no website is registered",
      "pitfalls": [
        "A document behind a login, or one that downloads rather than displays, cannot be reviewed. The test is whether a stranger can read it in a browser."
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-144",
      "slug": "brd-144",
      "title": "The registered vertical must match the business on the website",
      "statement": "The declared industry vertical must match the business the registered website actually describes.",
      "rationale": "The vertical is one of the inputs to use-case eligibility and to the trust score, and a reviewer checks it in the cheapest possible way: they open the site and see whether it looks like that kind of business. A mismatch reads as a brand describing itself as something safer than it is, which is a much less charitable reading than the truth — usually that the closest of twenty-three options was chosen quickly.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.vertical vs website content",
      "severity": "HIGH",
      "detectability": [
        "CRAWL"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "AWS"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Pick the vertical a stranger would choose after thirty seconds on your home page. Where nothing fits well, choose the one covering most of the revenue rather than the most flattering one. Done when the vertical and the site's own description of the business agree.",
      "example": "vertical: RETAIL for acmecoffee.com, which sells coffee — not HOSPITALITY because there is a café",
      "notes": "BRD-150 checks the value is one of the 23; BRD-151 asks whether it came from the right vocabulary. This rule is the third question: whether it is TRUE of the business, judged against the site.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-145",
      "slug": "brd-145",
      "title": "A display name is required, and so is the DBA field",
      "statement": "The display name must be populated within its length bound, and the DBA field must be populated even when it is identical to the legal name.",
      "rationale": "The display name is the string a consumer sees attributed to the messages, so an empty one leaves the brand identified only by a legal entity nobody recognises. The DBA field trips people separately: it reads as optional when the business does not trade under a different name, and Telnyx requires it populated regardless — repeating the legal name there is the expected answer, not a workaround.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.display_name + brand.dba",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "Telnyx"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Populate the display name with the name customers know you by, and copy it into the DBA field if you do not trade under anything else. Done when both fields hold a value, even if it is the same value twice.",
      "example": "display_name: Acme Coffee · dba: Acme Coffee — repeated deliberately, not left blank",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-146",
      "slug": "brd-146",
      "title": "The DBA must be consistent with the legal name and every other field",
      "statement": "The DBA must be recognisably the same business as the legal name, the website, and the campaign — not an unrelated third name.",
      "rationale": "Reviewers use the DBA as the bridge between a legal name nobody recognises and a website that carries a brand. When the DBA is a third, unrelated name, that bridge collapses and the registration reads as three businesses stapled together — which is what an unauthorised reseller registration actually looks like. Multi-brand retailers reach this honestly by putting the group name in one field and a shopfront in another.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.dba vs brand.company_name",
      "severity": "HIGH",
      "detectability": [
        "AI_FORM"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "AWS",
        "Bandwidth",
        "HighLevel"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30918",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Set the DBA to the name customers actually see from this brand — the one on the website header and in the message sender line. If the business genuinely trades under several names, register a separate brand per name rather than listing one and messaging under another. Done when the DBA, the website title and the name in the samples are the same business.",
      "example": "company_name: Acme Coffee Co, LLC · dba: Acme Coffee · website: acmecoffee.com — one business, three consistent renderings",
      "notes": "Bandwidth grades this MEDIUM and AWS HIGH; the strictest is kept per the strict-superset model.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-147",
      "slug": "brd-147",
      "title": "A DBA used publicly must be registered on the brand",
      "statement": "Any trading name the business uses publicly — on its site or in its messages — must be declared in the DBA field rather than substituted silently.",
      "rationale": "The consumer's only handle on who is texting them is the name in the message, so a name that appears there and nowhere in the registration breaks the identification the whole framework rests on. It is rarely deliberate: the messaging programme gets its own friendly name, the registration was filled in months earlier, and nobody connects the two.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.dba vs website and message content",
      "severity": "BLOCKING",
      "detectability": [
        "CRAWL",
        "EXTERNAL_DATA"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Twilio"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30918",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Add the public trading name to the brand's DBA field. Where more than one name is used publicly, register the one that appears in the messages — that is the one a recipient will try to match. Done when the name a customer sees in a text can be found on the brand record.",
      "example": "dba: Acme Coffee — where the site header, the samples and the HELP reply all say \"Acme Coffee\" but the legal name is Acme Coffee Co, LLC",
      "notes": "Whether a DBA is REGISTERED with the state is EXTERNAL_DATA and out of reach; what we can see is whether a publicly used name was declared to us. The user has to confirm separately that any DBA they rely on is properly filed where their state requires it, because a reviewer who looks it up and finds nothing treats the name as invented.",
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Is every trading name you use publicly — in messages, on the site — registered where your state requires a DBA to be filed?",
        "howToCheck": [
          "List the names a customer could see: the sender name in your texts, the name on the website header, the name on receipts.",
          "For each, confirm it is either the legal name or a DBA filed with the state or county that requires it.",
          "Put the name that appears in the messages in the brand's DBA field — that is the one a recipient will try to match."
        ],
        "failureLooksLike": "The messaging programme was given a friendly name of its own. A reviewer looks the name up, finds no filing behind it, and treats it as invented."
      }
    },
    {
      "id": "BRD-149",
      "slug": "brd-149",
      "title": "The opt-in evidence must be on the brand's own domain",
      "statement": "The website domain shown in the opt-in evidence must match the brand's registered domain.",
      "rationale": "Opt-in evidence naming a different company than the brand is the single clearest sign that the wrong entity was registered — the consent belongs to whoever is named on the page, and that is not the brand being registered. It is also what an ISV registration looks like from the outside, which is why reviewers treat it as decisive rather than as a filing error.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "evidence domain vs brand.website",
      "severity": "HIGH",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Twilio"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30927",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Attach evidence captured on the brand's own site. If the opt-in genuinely happens on another company's domain, that company is the brand — register them instead. Done when the domain visible in the evidence and the registered website are the same business.",
      "example": "evidence: https://cdn.acmecoffee.com/compliance/checkout-optin.png · website: https://acmecoffee.com — the same registrable domain",
      "pitfalls": [
        "A CDN or asset subdomain of the brand's own domain is fine; a hosting service on somebody else's domain is not, because the reviewer cannot tell whose page it was."
      ],
      "notes": "Compares the registrable domain of each hosted artifact against the brand website. What it cannot see is the domain rendered INSIDE a screenshot — an artifact hosted on the brand's CDN can still show another company's checkout — so a PASS here is a necessary condition rather than a sufficient one, and the vision rules judge the picture itself.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-150",
      "slug": "brd-150",
      "title": "The vertical must be one of the 23 registry values",
      "statement": "The industry vertical must be one of the 23 TCR values, and is required for every entity type except sole proprietor.",
      "rationale": "The vertical drives use-case eligibility and part of the trust score, and the registry rejects a value outside its own vocabulary rather than mapping it to the nearest match. The trap is that the neighbouring vocabularies are plausible: Twilio publishes a longer business-industry list, so NON_PROFIT and BANKING look like valid verticals and are not — TCR spells the first NGO and has no entry for the second.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.vertical",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "Telnyx",
        "Twilio"
      ],
      "applicability": {
        "excludeEntityTypes": [
          "SOLE_PROPRIETOR"
        ]
      },
      "applicabilityText": "Applies when the brand is NOT a sole proprietor.",
      "universal": false,
      "remediation": "Choose the vertical from the TCR list of 23. A charity is NGO, not NON_PROFIT; a bank is FINANCIAL, not BANKING. Done when the submitted string is character-identical to one of the 23 values.",
      "example": "vertical: NGO — the TCR value for a charity, where Twilio's list would say NON_PROFIT",
      "pitfalls": [
        "A form built against Twilio's business-industry enum will offer values TCR rejects, and the field will look correctly populated right up to the rejection."
      ],
      "notes": "The mechanical half of the vertical question. BRD-151 judges whether the chosen vertical is PLAUSIBLE for the business; this rule only asks whether the value exists. A vertical can pass here and fail there.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-151",
      "slug": "brd-151",
      "title": "Vertical must come from the correct provider-specific list",
      "statement": "The industry vertical must be chosen from the list the target platform uses, which is not always the TCR vertical list.",
      "rationale": "Twilio's business-industry enum and the TCR vertical list are different vocabularies with different values, so populating one from the other produces values the platform rejects or silently coerces. It is invisible in a form that renders whichever list it was built against.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.vertical",
      "severity": "MEDIUM",
      "detectability": [
        "AI_FORM"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "Twilio"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Pick the vertical from the list your submission target actually publishes, and re-check it if you switch providers.",
      "example": "TCR uses RETAIL; Twilio's business-industry list has separate values such as BANKING and JEWELRY.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-153",
      "slug": "brd-153",
      "title": "brandRelationship must be one of the five account tiers",
      "statement": "Outside the sole-proprietor tier, brandRelationship must be one of BASIC_ACCOUNT, SMALL_ACCOUNT, MEDIUM_ACCOUNT, LARGE_ACCOUNT or KEY_ACCOUNT.",
      "rationale": "This field describes the CSP's commercial relationship with the brand, not the brand's size, and it is mandatory — so a submission that leaves it out or invents a value is rejected on a field the customer has never heard of and the integrator guessed at. Nothing downstream depends on which tier is chosen, which is exactly why it gets filled in carelessly.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.brand_relationship",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR"
      ],
      "codes": [
        {
          "provider": "TCR",
          "code": "501",
          "remediable": true
        }
      ],
      "applicability": {
        "excludeEntityTypes": [
          "SOLE_PROPRIETOR"
        ]
      },
      "applicabilityText": "Applies when the brand is NOT a sole proprietor.",
      "universal": false,
      "remediation": "Set brandRelationship to the tier that describes your commercial relationship with this customer — BASIC_ACCOUNT is the honest answer for most self-serve registrations. Done when the value is one of the five, in upper case with the underscore.",
      "example": "brand_relationship: BASIC_ACCOUNT",
      "notes": "Checked only where a value is present: a registration that has not reached this field yet is undecided rather than wrong. The field is genuinely required at submission, so an empty one will be rejected by the API even though this rule stays quiet about it.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-154",
      "slug": "brd-154",
      "title": "The account tier cannot be changed more than once a quarter",
      "statement": "brandRelationship must not be changed more than once in any three-month period.",
      "rationale": "The tier feeds commercial reporting rather than compliance, so the registry rate-limits it instead of validating it — and the rejection arrives as a bare error code on an edit that seemed trivial. It bites during account reviews, when someone tidies up several brands at once and one of them was already touched last month.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.brand_relationship",
      "severity": "MEDIUM",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "TCR"
      ],
      "codes": [
        {
          "provider": "TCR",
          "code": "528",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Leave the tier as it is until three months have passed since the last change. Nothing about the brand's standing depends on it, so there is no cost to waiting — and no route to an exception if you do not.",
      "notes": "The cooldown is enforced at the registry against a change history we only see when the caller supplies it. The user has to know when the tier was last edited; where that is unknown, the safe assumption is that it was recent, because this field is usually only touched during exactly the kind of review that would touch it twice.",
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Do you know when this brand's account tier was last changed, and was it more than three months ago?",
        "howToCheck": [
          "Check the brand's edit history for a previous change to the tier.",
          "Where the date is unknown, assume it was recent — this field is usually only touched during exactly the kind of account review that would touch it twice."
        ],
        "failureLooksLike": "Someone tidies up several brands at once and one was already edited last month. The rejection is a bare error code on an edit that seemed trivial, and there is no exception route."
      }
    },
    {
      "id": "BRD-155",
      "slug": "brd-155",
      "title": "Regions of operation come from a five-value enum",
      "statement": "business_regions_of_operation must be drawn from AFRICA, ASIA, EUROPE, LATIN_AMERICA and USA_AND_CANADA.",
      "rationale": "The list is five continent-sized buckets, and every natural way to answer the question — a country, a state, \"North America\", \"Global\" — is outside it. The submission is rejected on a field that reads like free text, and the value that was typed is usually more precise than the one that is wanted.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.business_regions_of_operation",
      "severity": "MEDIUM",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Twilio"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30701",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Pick the buckets the business actually operates in from the five, and pass them as an array. A US-only business sends USA_AND_CANADA and nothing else. Done when every value is one of the five, in upper case.",
      "example": "business_regions_of_operation: [\"USA_AND_CANADA\"]",
      "notes": "A Twilio Trust Hub field that TCR does not carry, so it is checked only where it is populated. Not tagged with `providers`: the tag budget is reserved for genuine baseline divergences, and an unpopulated field costs nothing here.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-156",
      "slug": "brd-156",
      "title": "The representative needs an enum job position and their real title",
      "statement": "job_position must come from Director, GM, VP, CEO, CFO, General Counsel or Other, and the representative's exact business title must be supplied alongside it.",
      "rationale": "Two fields describe the same person and only one of them is constrained: the enum is what the API validates, and the free-text title is what a reviewer compares against the company's own website. Submitting the real title in the enum field fails validation, and submitting the enum value in the title field gives the reviewer nothing to corroborate.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.authorized_rep.job_position + .title",
      "severity": "MEDIUM",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Twilio"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30701",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Choose the closest enum value — Other is a legitimate answer for most titles — and put the person's actual title in the title field, spelled as it appears on the company site or their signature block. Done when the enum validates and the title is a real one.",
      "example": "job_position: CEO · title: Chief Executive Officer — or job_position: Other · title: Head of Customer Operations",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-157",
      "slug": "brd-157",
      "title": "Say whether you are the business or a reseller registering for it",
      "statement": "The business-identity and reseller flags must say correctly whether the registering party is the brand itself or an ISV, reseller or partner.",
      "rationale": "This flag is how the platform knows whether to expect the brand's own details or a third party's, and it changes what is treated as a contradiction: an agency address on a direct-customer registration is a finding, while the same address on a declared reseller registration is not. Setting it wrong turns correct data into suspicious data.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.business_identity + brand.is_reseller",
      "severity": "MEDIUM",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Twilio",
        "Telnyx"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30894",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Set the flag to direct_customer when the business is registering itself, and to isv_reseller_or_partner when you are registering on someone else's behalf. Declaring the reseller relationship does not weaken the registration — concealing it does. Done when the flag matches who filled the form in.",
      "example": "is_reseller: false · business_identity: direct_customer — for a business registering itself",
      "notes": "Only the internal consistency of the two fields is checkable here. Whether the declared answer is TRUE is BRD-160 and BRD-121, which read it against the campaign and the contact details.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-158",
      "slug": "brd-158",
      "title": "Social profiles corroborate a brand that is otherwise thin",
      "statement": "Social-media profile URLs should be supplied to strengthen brand verification.",
      "rationale": "Vetting scores partly on how much independent evidence exists that the business is real and has a history, and social profiles are the cheapest such evidence to supply — an account with years of posts corroborates a company far better than a website registered last month. Nothing rejects a brand for omitting them, which is why almost everyone does, including the businesses whose score most needed the help.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.social_profiles",
      "severity": "LOW",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Twilio"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30799",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Add the business's own profile URLs — the ones with real posting history, not a placeholder account created this week. Two or three established profiles are worth more than five empty ones. Done when the profiles are populated and each opens to the business.",
      "example": "social_profiles: [\"https://www.linkedin.com/company/acme-coffee\", \"https://instagram.com/acmecoffee\"]",
      "notes": "Advisory rather than a rejection, which is why it is LOW and why an empty field PASSES with the advice attached rather than failing: nothing is wrong with a registration that omits it, and failing one would be a false positive on every compliant brand. The rule fails only on URLs that are supplied and unusable. It earns its place because it is one of the very few ways a business can raise a trust score by supplying information rather than by paying for a vet.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-160",
      "slug": "brd-160",
      "title": "Register the message sender, not the agency or platform",
      "statement": "The brand must be the legal entity whose messages are sent — never the agency, ISV, reseller, or software platform acting on its behalf.",
      "rationale": "Consent runs to a specific sender, so the brand on the registration must be the business the consumer agreed to hear from. Registering the agency or platform instead breaks that chain and is the highest-frequency brand rejection in the corpus — 10 separate sources across 11 authorities call it out.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.company_name",
      "severity": "BLOCKING",
      "detectability": [
        "HUMAN",
        "AI_FORM"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "Twilio",
        "Telnyx",
        "Bandwidth",
        "AWS",
        "T-Mobile",
        "CTIA"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Register the brand under the legal entity that owns the customer relationship and whose name appears in the messages. If you are an agency or platform registering on behalf of a client, the client is the brand — register them, with their EIN and their website, and add yourself as the CSP rather than the brand.",
      "example": "Brand: Acme Coffee Co, LLC (the business texting its own customers) — not \"Northstar Marketing Group\" (the agency running the campaign).",
      "notes": "Highest-frequency brand rejection in the corpus (10 source rows, 11 authorities). A tool that fills the form from whatever website it was pointed at can actively induce this failure.",
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Is the legal entity on this brand the business whose name appears in the messages, rather than the agency or platform that sends them?",
        "howToCheck": [
          "Read one of your sample messages as a recipient would, and note which business it says is texting.",
          "Compare that business against the legal name and EIN on the brand. They must be the same entity.",
          "If you are an agency, ISV or reseller, your client is the brand and you are the CSP — register them, not yourself."
        ],
        "failureLooksLike": "The brand says Northstar Platform, Inc. and the message says \"Acme Coffee: your order is ready\". The consumer consented to hear from Acme, so Acme is the brand and Northstar is not."
      }
    },
    {
      "id": "BRD-163",
      "slug": "brd-163",
      "title": "Name the ISV on a toll-free verification filed for someone else",
      "statement": "Where a toll-free verification is submitted on behalf of an end business, the ISV or reseller name must be disclosed.",
      "rationale": "Toll-free verification asks who is filing as well as who is being verified, because the reviewer needs to know whether an unfamiliar contact in the submission is the business or its vendor. Leaving it out makes the ISV's own details look like inconsistencies in the end business's record, which is a much worse reading than the truth.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "tfv.isv_name",
      "severity": "MEDIUM",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Bandwidth"
      ],
      "codes": [
        {
          "provider": "Bandwidth",
          "code": "TFV 1301",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Populate the ISV name field with your own company name on every toll-free verification you file for a customer. Done when the submission names both the end business and the party filing it.",
      "example": "isv_name: Northstar Platform, Inc · company_name: Acme Coffee Co, LLC",
      "notes": "Applies on the toll-free verification path rather than to 10DLC brand registration; the condition lives in the check, which passes immediately for a 10DLC submission. Where the path is not declared the rule is silent rather than assuming one.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-164",
      "slug": "brd-164",
      "title": "The named contact must be authorised to act for the business",
      "statement": "The brand contact must be an authorised representative of the business, not a generic, third-party or aggregator name.",
      "rationale": "This person is treated as the party who attested to the registration, so the name matters when a carrier asks who authorised the programme. A vendor's account manager or a shared \"Marketing Team\" entry means nobody at the business did — and that is a materially different answer from the one the registration implies.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.authorized_rep",
      "severity": "HIGH",
      "detectability": [
        "HUMAN"
      ],
      "failureClass": "TERMINAL_EVIDENCE",
      "authorities": [
        "AWS",
        "Bandwidth",
        "HighLevel",
        "CTIA"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30972",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Name someone employed by the business with authority to commit it — an owner, an officer, or the manager who owns the messaging programme. Get their agreement before naming them, because they may be contacted about it.",
      "notes": "Nothing on the form shows whether the named person works for the business. What the user has to do is confirm the person is a real employee with authority and knows they have been named — a reviewer who calls the business and finds nobody by that name treats the whole registration as unverified.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Does the named representative work for the business, have authority to commit it, and know they have been named?",
        "howToCheck": [
          "Confirm the person is a real employee — an owner, an officer, or the manager who owns the messaging programme.",
          "Tell them they have been named and that they may be contacted about it.",
          "Rule out the two substitutes: a vendor's account manager, and a generic entry like \"Marketing Team\"."
        ],
        "failureLooksLike": "A reviewer calls the business and finds nobody by that name. The registration implies somebody at the business attested to it, and nobody did."
      }
    },
    {
      "id": "BRD-165",
      "slug": "brd-165",
      "title": "A toll-free contact needs a full first and last name",
      "statement": "The toll-free registration contact must be an authorised representative's full first and last name.",
      "rationale": "The contact name is checked against the business rather than stored, so a department, a role or a single word gives the reviewer nothing to check and the submission is refused. Teams supply \"Support\" or \"Marketing Team\" precisely because they are trying to avoid naming an individual, which is the opposite of what the field is for.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "tfv.contact_first_name + .contact_last_name",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Infobip"
      ],
      "codes": [
        {
          "provider": "Infobip",
          "code": "10000",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Name a real person who is authorised to act for the business, first and last name in their own fields. Done when both fields hold a person's name rather than a role or a department.",
      "example": "contact_first_name: Jane · contact_last_name: Doe",
      "notes": "Applies on the toll-free verification path; the check passes immediately for a 10DLC brand submission. Whether the named person is genuinely authorised is BRD-164, which nothing on the form can settle.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-166",
      "slug": "brd-166",
      "title": "The sender must be identified and authenticated before any message goes out",
      "statement": "Sufficient identifying information must be obtained to verify and authenticate the sender's identity before that sender sends any message.",
      "rationale": "This is the know-your-customer duty the whole registration framework implements, and it sits on the aggregator rather than on the brand: nobody may send until somebody has established who they are. It is worth stating explicitly because it explains why so many of the other brand rules are unyielding about evidence — they are how this obligation is actually discharged.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the brand identity bundle",
      "severity": "BLOCKING",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "CTIA"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Complete brand registration and identity verification before enabling any traffic, and keep the identity evidence on file for as long as the sender is active. Done when no number can send under this brand before its identity status is verified.",
      "notes": "CTIA Messaging Principles §3.2.4 places this duty on the CPaaS or aggregator, not on the brand, so it is not something a registration can satisfy by itself. What the user has to confirm is that their provider actually enforces it — a provider that lets traffic flow before verification is a risk to its customers rather than a convenience, because the enforcement lands later and harder.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Does your provider actually block traffic under this brand until its identity status is verified?",
        "howToCheck": [
          "Ask the provider directly, or test it: attempt a send under an unverified brand and see whether it is refused.",
          "Keep the identity evidence on file for as long as the sender is active — this duty sits on the aggregator, and the evidence is how it is discharged."
        ],
        "failureLooksLike": "A provider that lets traffic flow before verification looks like a convenience and is a liability: the enforcement lands later, on a live programme, and harder."
      }
    },
    {
      "id": "BRD-168",
      "slug": "brd-168",
      "title": "Consent must name the seller whose messages are delivered",
      "statement": "Where a reseller or agency sends, the consent must authorise messages delivered, or caused to be delivered, by the named seller.",
      "rationale": "Consent runs to a named party, and the FCC's definition covers messages a seller causes to be delivered as well as ones it sends itself — so consent naming the agency does not authorise the brand, and consent naming the brand does authorise its vendor. Getting this backwards is how a compliant-looking programme ends up with consent that covers nobody who is actually texting.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the consent text vs the sending entity",
      "severity": "HIGH",
      "detectability": [
        "AI_FORM"
      ],
      "failureClass": "TERMINAL_WEBSITE",
      "authorities": [
        "FCC"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Word the opt-in so it names the business the customer knows — the seller — and covers messages sent on its behalf: \"…to receive texts from Acme Coffee or its service providers.\" Done when the name in the consent is the brand on the registration.",
      "notes": "Applies where an agency or ISV sends on the brand's behalf. The condition lives in the criteria rather than in a tag, because no fact on the registration says who operates the sending — and the criteria open with the PASS boundary for the ordinary case where the brand sends for itself.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-169",
      "slug": "brd-169",
      "title": "Decide whether this brand is the seller or the telemarketer",
      "statement": "The brand's role — seller or telemarketer — must be established, because the obligations and the liability differ.",
      "rationale": "The two roles carry different duties, and a seller is liable for a vendor's failure to honour do-not-call requests even where the seller never touched the message. Businesses assume that engaging an agency transfers the exposure; it adds a second liable party instead. Knowing which side you are on decides who has to hold the consent records and who answers a complaint.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the brand's role classification",
      "severity": "MEDIUM",
      "detectability": [
        "AI_FORM"
      ],
      "failureClass": "TERMINAL_EVIDENCE",
      "authorities": [
        "FCC"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Write down which role this brand holds and make the consequences explicit in the vendor contract: who holds the consent records, who processes revocations, who answers a complaint. Done when both parties have the same answer in writing.",
      "notes": "A legal classification rather than a form field, so nothing about it can be validated at submission. The judgement flags which role the registration looks like; the user has to confirm it against their own contracts, because the answer decides where the liability sits rather than what to type.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-170",
      "slug": "brd-170",
      "title": "An agency arrangement does not shield either party in Virginia",
      "statement": "Virginia holds the telephone solicitor and the seller jointly liable, and an agency arrangement does not shield either from the other's failure.",
      "rationale": "Joint liability means both parties answer for the same violation, so the usual contractual comfort — the vendor indemnifies the brand, or the brand disclaims the vendor — allocates cost between them without reducing either one's exposure to the regulator. Businesses discover this after a complaint, when both names are on it.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the brand's role classification",
      "severity": "MEDIUM",
      "detectability": [
        "HUMAN"
      ],
      "failureClass": "TERMINAL_EVIDENCE",
      "authorities": [
        "Virginia SB 1339"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Where messages reach Virginia numbers, treat compliance as a shared duty rather than a delegated one: both parties keep consent records, and both can evidence how revocations are processed. Done when either party could answer a complaint without the other.",
      "notes": "A state-law exposure rather than a registration check, and nothing in a submission reveals where the recipients are. What the user has to do is establish whether their list reaches Virginia numbers and, if it does, make sure their own records would stand up on their own — an indemnity from a vendor is not a defence to the regulator.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Does your list reach Virginia numbers — and if so, could each party answer a complaint from its own records, without the other?",
        "howToCheck": [
          "Check the list for Virginia area codes and recipient states.",
          "Where it reaches them, confirm both the seller and the solicitor hold consent records and can evidence how revocations are processed.",
          "Read your vendor contract for what it actually does: an indemnity allocates cost between the parties, it is not a defence to the regulator."
        ],
        "failureLooksLike": "Both names are on the complaint. The contractual comfort each party relied on turns out to have reduced neither party's exposure."
      }
    },
    {
      "id": "BRD-172",
      "slug": "brd-172",
      "title": "Document every Texas exemption you rely on",
      "statement": "Where a Texas exemption is relied upon, the basis for it must be documented and retained.",
      "rationale": "Texas exemptions — publicly traded, insurer, supervised financial institution, FCC-regulated, non-profit, existing customer, majority brick-and-mortar — are affirmative defences, which means the burden of proving one sits with the business claiming it. An exemption that was true and undocumented is worth nothing at the point it is needed.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "Texas exemption evidence",
      "severity": "HIGH",
      "detectability": [
        "HUMAN"
      ],
      "failureClass": "TERMINAL_EVIDENCE",
      "authorities": [
        "Texas SB 140"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "For each exemption relied on, keep a short written record: which exemption, why it applies, and the evidence — the licence number, the registration, the customer relationship. Review it annually, because several of the exemptions can lapse without anyone noticing.",
      "notes": "Nothing in a registration says which exemptions a business relies on. The user has to identify them and write the basis down while it is easy to establish — the exemptions are affirmative defences, so an undocumented one fails at exactly the moment it matters.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "For each Texas exemption you rely on, is there a written record of which exemption, why it applies, and the evidence behind it?",
        "howToCheck": [
          "List the exemptions in play: publicly traded, insurer, supervised financial institution, FCC-regulated, non-profit, existing customer, majority brick-and-mortar.",
          "For each, write down the basis and the evidence — the licence number, the registration, the customer relationship — while it is still easy to establish.",
          "Review annually. Several of these lapse without anyone noticing."
        ],
        "failureLooksLike": "The exemption was true and undocumented. It is an affirmative defence, so the burden sits with you, and it fails at precisely the moment it is needed."
      }
    },
    {
      "id": "BRD-173",
      "slug": "brd-173",
      "title": "One brand per tax ID",
      "statement": "At most one brand may be registered against a given tax ID.",
      "rationale": "The tax ID is what the carriers attribute reputation and volume against, so a second brand on the same EIN splits the identity of one business in two and pools its allowances anyway (BRD-235). Businesses create the second one for entirely sensible reasons — a new division, a new agency, a fresh start after a rejection — and the duplicate is refused against a record they cannot see.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.ein across the registry",
      "severity": "BLOCKING",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Bandwidth",
        "Telnyx",
        "Bird",
        "SignalWire",
        "AWS",
        "Sinch"
      ],
      "codes": [
        {
          "provider": "Bandwidth",
          "code": "711",
          "remediable": true
        },
        {
          "provider": "Twilio",
          "code": "30898",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Run several campaigns under one brand rather than several brands under one EIN — the campaign is the unit that describes a programme, and there is no penalty for having many. Where a second brand is genuinely needed, at least one provider will accept it with a written business justification; ask before submitting.",
      "notes": "Absorbs BRD-176, the tenant-local case of the same uniqueness rule. The strictest model is kept: several providers allow exactly one brand per EIN, and one allows a second with written justification. What the user has to establish is whether a brand already exists on this EIN anywhere — including at a former agency — because the refusal will not say where the existing one is.",
      "catalogIds": [
        "BRD-176"
      ],
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Does a brand already exist against this tax ID anywhere — at any provider, including one a former agency used?",
        "howToCheck": [
          "Ask the customer who has sent SMS on their behalf, ever. The refusal will not tell you where the existing brand is.",
          "Plan for one brand per legal entity and several campaigns beneath it — there is no penalty for many campaigns.",
          "Where a second brand is genuinely needed, at least one provider accepts it with a written business justification. Ask before submitting."
        ],
        "failureLooksLike": "A new division, a new agency, or a fresh start after a rejection produces a second brand on the same EIN. It is refused against a record the business cannot see, and the allowances were pooled anyway."
      }
    },
    {
      "id": "BRD-174",
      "slug": "brd-174",
      "title": "Per-EIN brand counts are capped even where several are allowed",
      "statement": "Where a provider permits more than one brand per tax ID, the number is still capped and each additional brand needs a documented business reason.",
      "rationale": "The looser model is not an open door: the cap exists because a single business fragmented across many brands defeats the reputation model the framework runs on. Agencies reach the cap by creating a brand per client campaign rather than per client, and the refusal arrives on the one that mattered.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.ein across the registry",
      "severity": "HIGH",
      "detectability": [
        "EXTERNAL_DATA",
        "HUMAN"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Twilio"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30898",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Keep one brand per legal entity and use campaigns for everything below that. Where several brands on one tax ID are genuinely required, write the business reason down before submitting — you will be asked for it, and after a refusal it is too late.",
      "notes": "Absorbs OPS-366, which states the same minimisation duty and adds the warning against resubmitting after an EIN-reuse rejection — a second attempt on the same EIN is read as evasion rather than as a retry. The count is registry-wide and invisible to us; what the user has to do is keep their own tally of brands registered against each EIN, across every provider they use.",
      "catalogIds": [
        "BRD-175",
        "OPS-366"
      ],
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Do you keep your own tally of brands registered against each tax ID, across every provider you use?",
        "howToCheck": [
          "Count them. The registry-wide number is invisible to you and to us.",
          "Keep one brand per legal entity and use campaigns for everything below that.",
          "Where several are genuinely required, write the business reason down before submitting — you will be asked, and after a refusal it is too late."
        ],
        "failureLooksLike": "An agency creates a brand per client campaign rather than per client, hits the cap, and the refusal lands on the one that mattered. A second attempt on the same EIN after a reuse rejection is read as evasion rather than as a retry."
      }
    },
    {
      "id": "BRD-177",
      "slug": "brd-177",
      "title": "A duplicate on any identity field blocks the submission",
      "statement": "A brand submission is blocked where it matches an existing brand on legal name, registration number, mobile number, representative phone, email, website or stock symbol.",
      "rationale": "Duplicate detection runs across seven fields at once and reports the first collision it finds, so a registration can be refused for a field nobody thought was an identifier — a shared support email, a website reused across locations. It fires before the per-field rules, which is why the message is generic and the cause is usually not the field the team was looking at.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the seven-field duplicate key",
      "severity": "BLOCKING",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Twilio",
        "TCR"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30703",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Before resubmitting, check all seven fields against any other brand your organisation has registered: legal name, registration number, mobile number, representative phone, contact email, website and stock symbol. Change the one that genuinely belongs to the other brand rather than varying a value to get past the check.",
      "notes": "The consolidated duplicate key; the per-field rules (BRD-011, BRD-050, BRD-107, BRD-135) remain separate because each has its own limit semantics — some allow reuse up to a count, this one allows none. The collision is against the whole registry. What the user has to do is enumerate their own brands first, since a collision with their own earlier registration is far more likely than one with a stranger.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Have you checked all seven duplicate-key fields against every other brand your organisation has registered?",
        "howToCheck": [
          "Enumerate your own brands first — a collision with your own earlier registration is far more likely than one with a stranger.",
          "Compare each of the seven: legal name, registration number, mobile number, representative phone, contact email, website, stock symbol.",
          "Change the value that genuinely belongs to the other brand. Do not vary a value to get past the check."
        ],
        "failureLooksLike": "The refusal is generic and fires before the per-field rules, so it names no field. The cause is usually a shared support mailbox or a website reused across locations — something nobody thought was an identifier."
      }
    },
    {
      "id": "BRD-178",
      "slug": "brd-178",
      "title": "Brand contact details must be unique across brands",
      "statement": "Each brand must have its own contact address, email and phone; reusing them across brands is a policy violation.",
      "rationale": "Shared contact details across many brands is the signature of a reseller registering client traffic under its own details, which is the pattern the brand-per-EIN and consent-transfer rules exist to stop. Providers treat it as a violation serious enough to trigger deactivation rather than a mere rejection.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.email + brand.phone + brand.street",
      "severity": "HIGH",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "Twilio",
        "Bandwidth"
      ],
      "applicability": {
        "excludeEntityTypes": [
          "SOLE_PROPRIETOR"
        ]
      },
      "applicabilityText": "Applies when the brand is NOT a sole proprietor.",
      "universal": false,
      "remediation": "Use the client's own address, email and phone for each brand. If you are an agency, your details belong on the CSP record, never on the brand.",
      "example": "Brand contact: jane.doe@acmecoffee.com — not agency@northstarmarketing.com reused across ten brands.",
      "notes": "Detectable only against other brands in the same tenant, so it is surfaced as guidance until multi-brand state exists.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-181",
      "slug": "brd-181",
      "title": "A CSP has a default cap on how many brands it may register",
      "statement": "A CSP must not exceed the default cap of 1,000 registered brands without requesting an increase.",
      "rationale": "The cap is on the registering party rather than on any customer, so it is invisible to everyone whose brand is refused by it — a growing platform hits the ceiling and its next fifty customers see a rejection that has nothing to do with them. The increase is granted on request, which makes this pure operational hygiene: ask before you arrive.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the CSP brand count",
      "severity": "MEDIUM",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "TCR"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30712",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Track the brand count against the 1,000 cap and request an increase from TCR while there is headroom. Done when the increase is granted before the count reaches the ceiling rather than after registrations start failing.",
      "notes": "Absorbs OPS-364, which states the brand and campaign quotas together — BRD-182 is the per-brand half. The count belongs to the registering CSP rather than to any registration, so where it is not reported this reads as PASS with the cap stated: nothing in the submission indicates a breach, and the operator has to watch the number themselves.",
      "catalogIds": [
        "OPS-364"
      ],
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Do you know your CSP brand count against the 1,000 cap, and have you requested an increase while there is still headroom?",
        "howToCheck": [
          "Track the count. It belongs to the registering party rather than to any customer, so nothing in a rejection will attribute it.",
          "Request the increase from TCR before the ceiling, not after registrations start failing — it is granted on request."
        ],
        "failureLooksLike": "A growing platform hits the ceiling and its next fifty customers see a rejection that has nothing to do with them."
      }
    },
    {
      "id": "BRD-182",
      "slug": "brd-182",
      "title": "A brand has a default cap on how many campaigns it may carry",
      "statement": "A brand must not exceed the default cap of 50 campaigns without requesting an increase.",
      "rationale": "Because the guidance everywhere else is \"use campaigns rather than more brands\", a large sender following that advice arrives at this ceiling — and the refusal lands on a campaign that was ready to launch. The increase is available on request; the problem is entirely that nobody asks until the cap bites.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the campaign count under the brand",
      "severity": "MEDIUM",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "TCR"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "21732",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Retire campaigns you no longer send on, and request an increase before the count approaches 50. Done when the brand has headroom ahead of the next launch rather than at it.",
      "notes": "Where the campaign count is not reported this reads as PASS with the cap stated — nothing in the submission indicates a breach. The count is a property of the brand at the registry rather than of any one submission, so the operator has to watch it.",
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Does this brand have campaign headroom under the 50-campaign cap ahead of the next launch?",
        "howToCheck": [
          "Count the campaigns on the brand and retire the ones you no longer send on.",
          "Request an increase before the count approaches 50 rather than at it."
        ],
        "failureLooksLike": "A large sender follows the advice to use campaigns rather than more brands, arrives at the ceiling, and the refusal lands on a campaign that was ready to launch."
      }
    },
    {
      "id": "BRD-186",
      "slug": "brd-186",
      "title": "Some providers lock a verified brand entirely",
      "statement": "On at least one provider, a brand's details become uneditable once it is verified.",
      "rationale": "Where the lock applies there is no correction path at all — a typo discovered after verification means a new brand and a new campaign, which is a very different plan from an edit. Teams assume the usual re-verification cost (BRD-044) applies and find the field simply will not take a new value.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the brand record after verification",
      "severity": "MEDIUM",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "SignalWire"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Check the brand carefully before it verifies, not after. Where an edit is required on a locked brand, plan a new registration and the migration of the campaigns under it, and keep the old brand live until the new one is verified.",
      "notes": "Conditional on the submission target, and not tagged with `providers` — the tag budget is reserved for baseline divergences and this is checkable from the operation itself. What the user has to establish is whether their own provider locks verified brands: the answer decides whether a late correction costs a re-verification or a rebuild.",
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Does your provider lock a brand's details once it verifies?",
        "howToCheck": [
          "Ask the provider, or check its documentation, before the brand verifies — the answer decides whether a late correction costs a re-verification or a full rebuild.",
          "Where the lock applies, check the record carefully before verification and keep the old brand live if a replacement becomes necessary."
        ],
        "failureLooksLike": "A team assumes the usual re-verification cost and finds the field simply will not take a new value. A typo means a new brand and a new campaign."
      }
    },
    {
      "id": "BRD-189",
      "slug": "brd-189",
      "title": "A failed brand can be updated by API and not in the console",
      "statement": "Remediating a failed brand differs by interface: the API permits an update in place, while the console requires delete and recreate.",
      "rationale": "The same brand, the same fix, and two different procedures depending on where you are standing — so a team that reads the API documentation and works in the console concludes the update is broken. Deleting and recreating is also the more expensive of the two, because a new brand starts its verification from the beginning and takes its campaigns with it.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the remediation path",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Twilio"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30793",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Fix a failed brand through the API, where an update in place is accepted, rather than deleting and recreating it in the console. Note that the update is accepted only while the brand is in a failed state — a brand that has not failed cannot be updated this way at all.",
      "notes": "Absorbs OPS-345, which states which brand states accept an update at all. Conditional on the interface rather than on the provider, so it is not `providers`-tagged. What the user has to know is that the console path is not the only one available: an API update avoids the rebuild entirely.",
      "catalogIds": [
        "OPS-345"
      ],
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "If this brand has failed, are you fixing it through the API rather than deleting and recreating it in the console?",
        "howToCheck": [
          "Use the API update in place — the console path requires delete and recreate, which restarts verification and takes the campaigns with it.",
          "Note the update is accepted only while the brand is in a failed state; a brand that has not failed cannot be updated this way at all."
        ],
        "failureLooksLike": "A team reads the API documentation, works in the console, and concludes the update is broken — then rebuilds a brand that could have been edited."
      }
    },
    {
      "id": "BRD-191",
      "slug": "brd-191",
      "title": "The two bundle identifiers must not be transposed",
      "statement": "The customer-profile and A2P bundle identifiers must be distinct, belong to the same account, and not be swapped.",
      "rationale": "The two identifiers have the same prefix and the same length, sit next to each other in the request, and describe different objects — so transposing them produces a submission that validates structurally and fails on a message about bundle validation. It is one of the very few brand errors that is genuinely a typo rather than a misunderstanding.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the bundle identifiers",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Twilio"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30793",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Read both identifiers back from the account and confirm which is the customer profile and which is the A2P bundle before resubmitting. Fix the upstream profile first if it is the one at fault — updating the brand alone re-fails for the same reason. Done when the two are distinct and each is in its own field.",
      "example": "customer_profile_bundle_sid: BU1111… · a2p_profile_bundle_sid: BU2222… — two different identifiers, each in its own field",
      "notes": "Absorbs OPS-346, which adds that the upstream profile must be corrected first. Only the shape and the distinctness are checkable here; whether each identifier points at the right object needs the account, which is external.",
      "catalogIds": [
        "OPS-346"
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-194",
      "slug": "brd-194",
      "title": "Subscribe to brand status events instead of polling",
      "statement": "Brand status changes should be received as events on a webhook rather than discovered by polling.",
      "rationale": "Brand verification is asynchronous and can take days, and the event carries the granular failure reason that the status field alone does not — so a poller sees a state change with no explanation and has to guess at the cause. It also determines how quickly the campaign goes in behind it: an event-driven flow submits the moment the brand is ready, and a nightly poll can waste most of a day.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the webhook configuration",
      "severity": "HIGH",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "TCR",
        "Twilio",
        "Telnyx"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Subscribe to the brand identity status event and read the failure reason from its payload. Wait for the event before making the next call rather than polling on a timer. Done when a brand state change arrives as a webhook carrying the reason.",
      "notes": "Absorbs BRD-193, which names the webhook carrying the granular failure reason, and OPS-347, which adds waiting for the event before the next call. The webhook belongs to the integration rather than to a registration, so where it is not reported this is undecided rather than passing — the product should ask rather than assume.",
      "catalogIds": [
        "BRD-193",
        "OPS-347"
      ],
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Are brand status changes arriving on a webhook that carries the failure reason, rather than being discovered by polling?",
        "howToCheck": [
          "Subscribe to the brand identity status event and read the granular failure reason from its payload — the status field alone does not carry it.",
          "Wait for the event before making the next call rather than polling on a timer."
        ],
        "failureLooksLike": "A poller sees a state change with no explanation and guesses at the cause, and a nightly poll wastes most of a day before the campaign goes in behind it."
      }
    },
    {
      "id": "BRD-195",
      "slug": "brd-195",
      "title": "Deactivate every campaign before deleting a brand",
      "statement": "All campaigns on a brand must be deactivated before the brand can be deleted.",
      "rationale": "The deletion is refused while campaigns are attached, which is a good outcome — the alternative would be live traffic against a brand that no longer exists. It matters because the refusal arrives in the middle of a decommissioning that has usually already been announced, and the campaigns have their own minimum age before they can be deactivated.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the campaign states under the brand",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "TCR",
        "Twilio"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30710",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Deactivate each campaign first, allow for the campaign minimum age before it can be deactivated, and delete the brand last. Done when the brand carries no active campaigns at the moment of deletion.",
      "notes": "Absorbs OPS-169, which states the same precondition and adds the campaign minimum age — a campaign registered days ago may not be deactivatable yet, which turns a same-day decommissioning into a multi-day one.",
      "catalogIds": [
        "OPS-169"
      ],
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Is every campaign on this brand already deactivated, and has each cleared its minimum age?",
        "howToCheck": [
          "Deactivate the campaigns first, then delete the brand.",
          "Check each campaign's age — one registered days ago may not be deactivatable yet, which turns a same-day decommissioning into a multi-day one."
        ],
        "failureLooksLike": "The deletion is refused mid-decommissioning, after the date has already been announced, because a campaign registered last week cannot yet be switched off."
      }
    },
    {
      "id": "BRD-197",
      "slug": "brd-197",
      "title": "Brand deletion cannot be undone",
      "statement": "A deleted brand cannot be reactivated; the deletion is final.",
      "rationale": "There is no restore, so a brand deleted to tidy an account takes its verification, its vetting and its history with it — and rebuilding means paying the fees again and waiting out the verification again. Deletion is offered next to deactivation in most interfaces, and only one of the two is reversible.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the delete request",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "TCR"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Deactivate the campaigns and leave the brand in place unless you are certain. If the goal is to stop traffic, that is what deactivation is for; deletion is only for a brand you will never use again. Done when the decision is deliberate rather than housekeeping.",
      "notes": "The registry offers no restore path and neither does any provider. What the user has to weigh before confirming is the cost of rebuilding: the verification fee, any vetting fee, the vetting lead time, and re-registering every campaign under a new brand.",
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Are you certain this brand will never be used again — or do you actually want deactivation?",
        "howToCheck": [
          "If the goal is to stop traffic, deactivate. Deletion is final and there is no restore path at the registry or at any provider.",
          "Price the rebuild before confirming: the verification fee, any vetting fee, the vetting lead time, and re-registering every campaign under a new brand."
        ],
        "failureLooksLike": "A brand is deleted to tidy an account and takes its verification, its vetting and its history with it. Deletion sits next to deactivation in most interfaces and only one of the two is reversible."
      }
    },
    {
      "id": "BRD-199",
      "slug": "brd-199",
      "title": "Do not move suspended traffic onto a new brand",
      "statement": "Traffic under suspension or carrier review must not be migrated to a new brand or campaign.",
      "rationale": "Re-registering to escape a suspension is read as evasion rather than as remediation, and it escalates from a suspended campaign to a terminated account — a far worse outcome than the original finding. It is a natural move under pressure: the campaign is blocked, a new brand takes a day, and the send is due.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the brand or campaign migration",
      "severity": "BLOCKING",
      "detectability": [
        "HUMAN",
        "UNDETECTABLE_PRE_SUBMISSION"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Twilio"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "21731",
          "remediable": false
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Work the suspension where it is: answer the carrier review, correct what it identified, and appeal. Do not register a replacement brand or campaign while a review is open, and tell whoever is under deadline pressure why.",
      "notes": "Nothing in a new registration reveals that an old one is suspended, so this is a rule the user has to apply themselves. What they must do is check whether any open suspension or carrier review exists on the account before registering a replacement — and if one does, treat the registration as unavailable until it is resolved.",
      "catalogIds": [
        "OPS-147"
      ],
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Is there any open suspension or carrier review against this business right now?",
        "howToCheck": [
          "Check the account for open reviews before registering any replacement brand or campaign — nothing in a new registration reveals an old suspension.",
          "Where one is open, work it where it is: answer the review, correct what it identified, appeal.",
          "Tell whoever is under deadline pressure why a new registration is not the way out."
        ],
        "failureLooksLike": "The campaign is blocked, a new brand takes a day, and the send is due. Re-registering reads as evasion and escalates a suspended campaign into a terminated account."
      }
    },
    {
      "id": "BRD-200",
      "slug": "brd-200",
      "title": "A suspension follows the tax ID to the next brand",
      "statement": "After a suspension, new brands created on the same tax ID should be expected to be restricted.",
      "rationale": "The suspension attaches to the EIN rather than to the brand or the account, so it follows the business across providers — which means switching CSP does not reset it, and the new provider cannot lift it either. Businesses change provider precisely because the old one suspended them, and arrive at the same restriction with a second onboarding already paid for.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.ein after a suspension",
      "severity": "BLOCKING",
      "detectability": [
        "EXTERNAL_DATA",
        "UNDETECTABLE_PRE_SUBMISSION"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Twilio"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "21731",
          "remediable": false
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Resolve the original suspension rather than moving. If the business genuinely has a new programme, expect the new brand to carry restrictions from the start and be ready to evidence what changed — the review will ask.",
      "notes": "Absorbs OPS-181, which states the same EIN-level scope across CSPs. Suspension history is not visible in a registration. What the user has to establish is whether this EIN has ever been suspended anywhere — the answer determines whether a new registration is worth attempting at all, and a provider change will not help.",
      "catalogIds": [
        "OPS-181"
      ],
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Has this tax ID ever been suspended, at any provider?",
        "howToCheck": [
          "Establish the suspension history for the EIN before starting a new registration. It attaches to the tax ID, not to the brand or the account, so changing provider does not reset it.",
          "Where a suspension exists, resolve it rather than moving — the new provider cannot lift it either.",
          "If the business genuinely has a new programme, be ready to evidence what changed. The review will ask."
        ],
        "failureLooksLike": "A business changes provider precisely because the old one suspended it, and arrives at the same restriction with a second onboarding already paid for."
      }
    },
    {
      "id": "BRD-203",
      "slug": "brd-203",
      "title": "The starter brand class is deprecated",
      "statement": "A deprecated starter-class brand must not be created or updated.",
      "rationale": "The class is disabled rather than discouraged, so both creation and update are refused — which means an existing starter brand cannot be corrected in place either, and the only route forward is migration to a standard class. Integrations built against the older documentation still send it, and the failure names the class rather than explaining that it is gone.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the brand class",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Twilio"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "21726",
          "remediable": false
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Register as a standard or low-volume standard brand instead. Where a starter brand already exists, migrate it rather than trying to update it — updates to the class are refused along with creations. Done when the brand class is one that is still supported.",
      "example": "brand_class: LOW_VOLUME_STANDARD — the supported low-cost route, in place of the deprecated STARTER class",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-204",
      "slug": "brd-204",
      "title": "Test against mock brands, not real ones",
      "statement": "Non-production submissions should use mock brands so fees are not charged and duplicate detection is not polluted.",
      "rationale": "A test registration is a real registration: it charges the fee, it consumes the identity fields, and it lands in the duplicate index — so the real submission that follows collides with the rehearsal. Mock brands exist precisely for this and cost nothing, but they are opt-in and easy to miss during an integration.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.mock",
      "severity": "LOW",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Twilio",
        "Telnyx"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Set the mock flag on every non-production submission, and use test rather than real identity values inside it. Done when no fee is charged and the real EIN, website and email have not been consumed by a rehearsal.",
      "example": "mock: true on every integration and staging submission",
      "notes": "Absorbs OPS-350, which states the same testing practice and the constraints mock records carry — a mock brand does not verify and cannot carry live campaigns, so it proves the integration rather than the registration. Nothing in a submission says whether it is a rehearsal, so a real brand with no mock flag passes: the check reports only the shape it can see.",
      "catalogIds": [
        "OPS-350"
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-207",
      "slug": "brd-207",
      "title": "Campaigns cannot be submitted while vetting is in review",
      "statement": "A campaign must not be submitted while the brand's vetting is still in review.",
      "rationale": "The campaign is evaluated against the brand's standing at the moment it arrives, so one submitted mid-review is judged against an unfinished brand and refused — and the refusal names the campaign, which sends people to rewrite copy that was never the problem. Teams do it because the vet takes days and the campaign is ready now.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the vet state",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "AWS"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Wait for the vet to reach a final state before submitting the campaign. Subscribe to the brand status event (BRD-194) rather than polling, so the campaign goes in the moment the brand is ready instead of the next time somebody checks.",
      "notes": "The wait is at the vetting provider and nothing on our side shortens it. What the user has to do is sequence the two submissions — brand first, campaign after the vet lands — because a campaign refused for this reason still consumes a submission and, on some providers, a fee.",
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Has the brand's vet reached a final state, rather than still being in review, at the moment the campaign goes in?",
        "howToCheck": [
          "Read the vet status on the brand immediately before submitting the campaign.",
          "Subscribe to the brand status event rather than polling, so the campaign goes in the moment the brand is ready instead of the next time somebody checks."
        ],
        "failureLooksLike": "The campaign is ready and the vet takes days, so it is submitted anyway. The refusal names the campaign, and copy that was never the problem gets rewritten."
      }
    },
    {
      "id": "BRD-208",
      "slug": "brd-208",
      "title": "A score below the threshold means fixing the data, not re-vetting",
      "statement": "Where the vetting score is below the carrier or use-case threshold, the underlying brand data must be corrected before a re-vet.",
      "rationale": "The score is computed from the brand data and the public record behind it, so re-running the same examination against the same inputs returns the same number — and the cooldown means you only get to find that out every three months. The productive move is unglamorous: correct the address, publish the phone number, fix the website, then re-vet.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.vetting_score",
      "severity": "HIGH",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "AWS",
        "Sinch",
        "Infobip"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Work the inputs the score reads: an exact address match, a phone that answers, a website that names the business, social profiles, a mailbox on the brand domain. Then re-vet once, after the cooldown. Done when the underlying data has changed before the second examination.",
      "notes": "The score and its threshold are held by the vetting provider. What the user has to do is treat a low score as a data problem rather than a verdict — most of the inputs are things they control, and BRD-211 lists the few that they do not.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Have you corrected the data the score reads — address, phone, website, mailbox, social profiles — before ordering another vet?",
        "howToCheck": [
          "Treat a low score as a data problem, not a verdict. Most of its inputs are things you control.",
          "Work them in order: an exact address match, a phone that answers, a website that names the business, social profiles, a mailbox on the brand domain.",
          "Then re-vet once, after the cooldown."
        ],
        "failureLooksLike": "The same examination is re-run against unchanged inputs and returns the same number — and the three-month cooldown means that is the only answer available until spring."
      }
    },
    {
      "id": "BRD-209",
      "slug": "brd-209",
      "title": "The score maps to specific throughput terms",
      "statement": "The vetting score determines the carrier class and daily throughput the brand receives, and 75 or above is the target.",
      "rationale": "Score bands are the mechanism the whole vetting purchase exists for, and they are steep: 75 and above buys the top class and 200,000 messages a day, while 25 to 49 buys 10,000 and 1 to 24 buys 2,000. Promising a customer volume before the score is known is promising something you do not control, and the gap between bands is a factor of twenty rather than a matter of degree.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.vetting_score",
      "severity": "HIGH",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "TCR",
        "AT&T",
        "T-Mobile"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Read the throughput off the band rather than off the fee: 75–100 gives AT&T Class A/B and T-Mobile Top at 200,000/day; 50–74 gives C/D and High Mid at 40,000; 25–49 gives Low Mid at 10,000; 1–24 gives Low at 2,000. Size the programme against the band you actually hold.",
      "notes": "Absorbs OPS-129, which states the same mapping and warns against promising terms the score cannot deliver. The score is issued by the vetting provider after the fact, so what the user has to do is avoid committing to a send volume until the band is known — and where a date is fixed, order the vet early enough to re-work the plan if the band comes in low.",
      "catalogIds": [
        "OPS-129"
      ],
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Have you avoided committing to a send volume before the vetting band is known?",
        "howToCheck": [
          "Read the throughput off the band, not off the fee: 75–100 is 200,000 a day, 50–74 is 40,000, 25–49 is 10,000, 1–24 is 2,000.",
          "Where a send date is already fixed, order the vet early enough to re-plan if the band comes in low."
        ],
        "failureLooksLike": "A customer is promised a volume before the score exists. The gap between adjacent bands is a factor of twenty, so the shortfall is not a matter of degree."
      }
    },
    {
      "id": "BRD-210",
      "slug": "brd-210",
      "title": "A low trust score blocks or narrows campaign registration",
      "statement": "A provider trust score at or below the gate blocks campaign registration entirely, and one just above it restricts which use cases are available.",
      "rationale": "This is a second score, computed by the provider rather than by the vetting partner, and it gates the use cases a brand may register at all — so a brand can be verified, vetted, and still unable to register the campaign it exists for. The rejection names the carrier rather than the score, which sends teams to look at their campaign copy.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.trust_score",
      "severity": "HIGH",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Twilio",
        "AT&T"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Where campaign registration is blocked with a carrier-qualification message, check the trust score before editing the campaign. Raising it means improving the brand data and, usually, buying a standard vet — the campaign is not the thing that failed.",
      "notes": "The trust score is the provider's own and is not exposed on the brand record we see. What the user has to do is ask their provider for the score when a campaign is refused on carrier qualification, because that one number explains a rejection that otherwise reads as a content problem.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "When a campaign is refused on carrier qualification, have you asked your provider for the brand's trust score before editing the campaign?",
        "howToCheck": [
          "Ask the provider directly for the trust score — it is theirs, computed separately from the vetting score, and it is not on the brand record you can see.",
          "Where the score is the cause, raise it by improving brand data and usually by buying a standard vet. The campaign is not the thing that failed."
        ],
        "failureLooksLike": "The rejection names the carrier rather than the score, so the team rewrites campaign copy for a week. A brand can be verified, vetted, and still barred from the use case it exists for."
      }
    },
    {
      "id": "BRD-211",
      "slug": "brd-211",
      "title": "Some score inputs cannot be fixed by editing the form",
      "statement": "Company size, years in operation and domain age drive the trust score and cannot be improved by data entry.",
      "rationale": "Once a business understands the score is data-driven, the reasonable next step is to improve the data — and several of the largest inputs are facts about the company's history rather than fields on a form. Saying so plainly stops a team spending a week polishing a record that was already accurate, and redirects them to the inputs that do move.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the firmographic profile",
      "severity": "LOW",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "HighLevel"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Accept the firmographic inputs and work the ones you control: an exact address match, a reachable phone, a website that describes the business, social profiles with history, a contact mailbox on the brand domain. For a genuinely new company, plan around the lower band rather than trying to raise it.",
      "notes": "Advisory, and it exists to stop wasted effort. What the user has to accept is that a young company with a new domain scores lower than an old one with the same paperwork — the route to volume for them is a campaign-level one, not a better-filled brand form.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Do you accept that company age, size and domain age set part of this score, and have you switched your effort to the inputs you control?",
        "howToCheck": [
          "Stop polishing a record that is already accurate. Company size, years in operation and domain age are facts about history, not fields.",
          "Work what does move: an exact address match, a reachable phone, a website that describes the business, social profiles with history, a contact mailbox on the brand domain.",
          "For a genuinely new company, plan around the lower band rather than trying to raise it."
        ],
        "failureLooksLike": "A week spent re-entering correct data. A young company with a new domain scores below an old one with identical paperwork, and the route to volume for it is campaign-level, not a better-filled form."
      }
    },
    {
      "id": "BRD-212",
      "slug": "brd-212",
      "title": "Vetting is not a remedy for a rejection",
      "statement": "External vetting exists to raise throughput, not to reverse a rejection, and it is not guaranteed to raise anything.",
      "rationale": "The instinct after a refusal is to buy the most expensive verification available, and it is precisely the wrong move: the vet examines the same data that was just refused, so it returns the same answer and charges for it. What fixes a rejection is correcting the brand data or filing an appeal — and a vet ordered on uncorrected data is money spent to confirm the problem.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the reason a vet is being ordered",
      "severity": "MEDIUM",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Bandwidth",
        "AWS"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Correct the brand data the rejection pointed at, or file an identity appeal with documentation. Order the vet afterwards, and only if the throughput you need is above what a verified brand gets by default. Done when the identity status is resolved before any vet is bought.",
      "example": "Fix the legal name to match the CP-575, then re-verify — rather than ordering a standard vet against the same unchanged name",
      "notes": "Absorbs OPS-305, which states the same two facts: vetting is not a rejection remedy, and a top standard score already buys the best available terms.",
      "catalogIds": [
        "OPS-305"
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-214",
      "slug": "brd-214",
      "title": "An enhanced vet buys nothing on top of a top standard score",
      "statement": "An enhanced vet must not be ordered where the standard vet has already returned a score at the top band.",
      "rationale": "Throughput terms are set by score bands, and the top band is the top band — a higher-grade vet against a score already at 75 or above produces the same carrier terms for a second fee. It is bought in good faith by teams who read \"enhanced\" as \"better\" rather than as \"a different examination of the same company\".",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.vetting_score + vet class",
      "severity": "MEDIUM",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Keep the standard vet. If throughput is still short of what the programme needs, the constraint is the carrier tier rather than the vet class, and the route up is campaign-level rather than another purchase. Done when no second vet is ordered against a score of 75 or more.",
      "example": "vetting: STANDARD, score 82 — and no enhanced vet ordered on top of it",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-215",
      "slug": "brd-215",
      "title": "The vetting provider must support this entity type and country",
      "statement": "The chosen vetting provider must support the brand's entity type and country of registration.",
      "rationale": "The providers cover different ground — one takes public, private, non-profit and government brands, another only US private and public companies, and the political route is import-only — so an order placed with the wrong one is refused after it is paid for. Nothing in the ordering flow narrows the list to the ones that can actually take your brand.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "vet provider vs brand.entity_type / brand.country",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR"
      ],
      "codes": [
        {
          "provider": "TCR",
          "code": "525",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Check the provider's coverage before ordering: Aegis takes public, private, non-profit and government brands; WMC takes US private and public companies only; Campaign Verify is political and import-only. Done when the provider you order from lists your entity type and country.",
      "example": "vetting provider: AEGIS for a NON_PROFIT brand — WMC does not cover non-profits",
      "notes": "The coverage matrix is published by TCR and changes as providers are added. Only the two documented exclusions are checked here — WMC's US-private-and-public-only scope, and Campaign Verify being import-only — so a provider passing this check should still be confirmed against the current matrix.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-216",
      "slug": "brd-216",
      "title": "An imported vet must match the brand exactly, and carry its token",
      "statement": "On a vet import, the legal name and entity type must match the vetting report exactly, and the vetting token must be supplied.",
      "rationale": "The import attaches somebody else's examination to this brand, so the registry checks that the two describe the same company before accepting it — and it compares strings. A report issued to \"Acme Coffee Company\" cannot be imported onto a brand registered as \"Acme Coffee Co, LLC\" even though everyone involved knows they are the same business.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the vet import payload",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR"
      ],
      "codes": [
        {
          "provider": "TCR",
          "code": "538",
          "remediable": true
        },
        {
          "provider": "TCR",
          "code": "520",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Compare the report against the brand field by field before importing, and correct whichever is wrong — usually the brand, since the report reflects what the vetting provider verified. Supply the verification certificate token with the import. Done when name and entity type match character for character and the token is attached.",
      "example": "vet report legal name: Acme Coffee Co, LLC · brand company_name: Acme Coffee Co, LLC · token: supplied",
      "pitfalls": [
        "Correcting the brand name to match the report is itself an identity change (BRD-044), so do it before the import rather than during it."
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-217",
      "slug": "brd-217",
      "title": "Some vet classes cannot be imported at all",
      "statement": "An Authentication+ class vet must not be submitted for import — the class does not support it.",
      "rationale": "Authentication+ verifies a live second factor rather than producing a transferable report, so there is nothing to import and the attempt is refused rather than queued. It is a reasonable thing to try: every other class can be imported, and the API takes the same shape for all of them.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the vet import class",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR"
      ],
      "codes": [
        {
          "provider": "TCR",
          "code": "525",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Order the Authentication+ vet directly on the brand instead of importing one. Where you already hold a report from elsewhere, only the standard and political classes can be brought across. Done when no import is attempted for the Authentication+ class.",
      "example": "vet import class: STANDARD — Authentication+ is ordered directly on the brand instead",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-218",
      "slug": "brd-218",
      "title": "Import the same token into every instance of the same brand",
      "statement": "Where the same brand is registered by more than one CSP, the same vetting token must be imported into each instance.",
      "rationale": "Throughput follows the vet, and the vet is attached to a brand instance rather than to the business — so a brand registered through two CSPs with the token imported into only one of them sends fast on one route and slowly on the other, for no visible reason. Only the Aegis standard token can be reused this way; every other partner issues single-use tokens.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the vet token across brand instances",
      "severity": "HIGH",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Import the same Aegis standard token into each duplicate brand instance, rather than ordering a fresh vet per CSP. Done when every instance of the brand reports the same vetting score.",
      "example": "vetting token: the same Aegis certificate imported into both the Twilio and the Telnyx brand instances",
      "pitfalls": [
        "Political tokens are single-use (BRD-246) and cannot be spread this way — the reuse rule is specific to the Aegis standard class."
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-221",
      "slug": "brd-221",
      "title": "Respect the cooldown before re-ordering a vet",
      "statement": "A vet must not be re-ordered against unchanged brand information, nor more than once in three months after the first post-registration re-vet.",
      "rationale": "A re-vet examines the same records, so ordering one against unchanged data returns the same score and charges for it — which is why the registry rate-limits the attempt rather than trusting people not to make it. The cooldown catches teams who are working the problem hard: three orders in a fortnight after a disappointing score is a very natural response and none of them can succeed.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the re-vet request + the brand diff",
      "severity": "MEDIUM",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "TCR",
        "Telnyx"
      ],
      "codes": [
        {
          "provider": "TCR",
          "code": "525",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Change the underlying brand data first — the firmographic inputs a vet reads — and then wait out the three months. If the score was the problem, the productive move is correcting the address, the website and the contact details rather than re-running the same examination.",
      "notes": "Merges the per-class cooldowns the catalog records separately (BRD-219 for RCS/RBM vetting, BRD-220 for the Telnyx window) into the one rule they describe: re-ordering inside any of them is refused or wasted. The window is enforced at the registry against a history we only see when the caller supplies it, so a re-order with no date attached is reported as undecided rather than allowed.",
      "catalogIds": [
        "BRD-219",
        "BRD-220"
      ],
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Has the brand data behind the score actually changed since the last vet, and is the three-month cooldown clear?",
        "howToCheck": [
          "Find the date of the last vet order. Inside the window, a re-order is refused or wasted.",
          "Before re-ordering, change what the vet reads: the address, the website, the published phone number, the contact details.",
          "Three orders in a fortnight after a disappointing score is a natural response and none of them can succeed."
        ],
        "failureLooksLike": "The same examination is re-run against the same records and returns the same number, having charged for it — and the cooldown means you find out every three months."
      }
    },
    {
      "id": "BRD-222",
      "slug": "brd-222",
      "title": "Editing the brand expires a completed vet",
      "statement": "A completed vet expires when the brand information behind it changes.",
      "rationale": "The vet certifies the brand as it stood, so an edit invalidates it in the same way a change of address invalidates an identity document — and the expiry is silent. Throughput drops back to the unvetted tier and the first anyone knows is a queue building on a send that used to clear.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the brand diff vs the vet state",
      "severity": "HIGH",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "TCR"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Batch brand edits and make them before ordering the vet, not after. Where an edit is unavoidable on a vetted brand, budget for re-ordering the vet and expect the cooldown in BRD-221 to apply to it.",
      "notes": "The expiry happens at the registry when the change lands. What the user has to do is treat a completed vet as pinned to the current brand record: check whether an edit is worth losing it before making it, because getting it back costs the fee again and the time again.",
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Is this brand edit worth losing the completed vet that is pinned to the current record?",
        "howToCheck": [
          "Check whether a completed vet is attached before making the edit.",
          "Batch edits and make them before ordering the vet, not after.",
          "Where the edit is unavoidable, budget for re-ordering the vet and expect the three-month cooldown to apply."
        ],
        "failureLooksLike": "The expiry is silent. Throughput drops to the unvetted tier and the first anyone knows is a queue building on a send that used to clear."
      }
    },
    {
      "id": "BRD-223",
      "slug": "brd-223",
      "title": "Website and contact email must be in place before an identity-plus vet",
      "statement": "The brand website and business contact email must be populated before an Authentication+ or RBM vet is ordered.",
      "rationale": "These vets verify the brand through its own domain and mailbox, so ordering one before either exists submits an examination with nothing to examine — it is refused on a missing field after the fee is taken. The two fields are optional on an ordinary brand, which is exactly why they are empty at the moment somebody decides to order the vet.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.website + brand.business_contact_email",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR"
      ],
      "codes": [
        {
          "provider": "TCR",
          "code": "501",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Populate the brand website and the business contact email, and let the update settle on the brand record, before placing the vet order. Done when both fields read back from the brand and the mailbox has been tested (BRD-119).",
      "example": "website: https://acmecoffee.com · business_contact_email: jane.doe@acmecoffee.com — both present before the order",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-224",
      "slug": "brd-224",
      "title": "Public companies must clear Authentication+ before campaigns",
      "statement": "A PUBLIC_PROFIT brand must reach identity VERIFIED with Authentication+ ACTIVE before any campaign can be registered.",
      "rationale": "Authentication+ is a two-factor identity confirmation sent to the registered business contact, and it gates campaign creation for public companies specifically. Vendor guidance frequently describes TCR 2FA as universal; AWS is explicit that it applies only to PUBLIC_PROFIT, so applying it everywhere wastes time and applying it nowhere blocks public brands.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.identity_status",
      "severity": "BLOCKING",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "TCR",
        "AWS"
      ],
      "applicability": {
        "entityTypes": [
          "PUBLIC_PROFIT"
        ]
      },
      "applicabilityText": "Applies when the brand is a public company.",
      "universal": false,
      "remediation": "Complete TCR Authentication+ (two-factor identity confirmation) for the brand before submitting campaigns.",
      "notes": "AWS is explicit that TCR 2FA applies only to PUBLIC_PROFIT. Vendor blogs routinely describe it as universal — it is not.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Does the brand show identity VERIFIED with an Authentication+ vet recorded as ACTIVE, before any campaign is submitted?",
        "howToCheck": [
          "Open the brand record at your provider and read two things: the identity status, and the list of vets attached to it.",
          "Confirm an Authentication+ (two-factor identity) vet is present and ACTIVE rather than merely ordered."
        ],
        "failureLooksLike": "The brand reads VERIFIED and looks finished, but carries no Authentication+ vet. Every campaign against it is refused, and the refusal names the campaign rather than the missing vet."
      }
    },
    {
      "id": "BRD-225",
      "slug": "brd-225",
      "title": "Authentication+ must now be ordered explicitly",
      "statement": "Under Authentication+ 2.0 the vet must be ordered explicitly after the identity check; it no longer runs automatically.",
      "rationale": "It used to be automatic, so every runbook, integration and mental model built before the change assumes it will happen on its own. It does not: the brand verifies, nobody orders the vet, and the public-company brand sits without the Authentication+ status that gates its campaigns — with no error anywhere, because nothing failed.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the Authentication+ vet order",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "TCR"
      ],
      "applicability": {
        "entityTypes": [
          "PUBLIC_PROFIT"
        ]
      },
      "applicabilityText": "Applies when the brand is a public company.",
      "universal": false,
      "remediation": "After the identity check completes, place the Authentication+ order explicitly and watch for the 2FA mail. Add the order as a step in your onboarding runbook — its absence produces no error, so nothing will remind you.",
      "notes": "The order is an action at the registry rather than a field on the registration. What the user has to do is remember it: a public brand that verified but was never Authentication+ vetted looks healthy and cannot register campaigns.",
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Has the Authentication+ vet been ordered explicitly, as a step in your runbook, after the identity check completed?",
        "howToCheck": [
          "Open the brand and confirm an Authentication+ order exists. It used to run automatically and no longer does.",
          "Add the order to the onboarding runbook — its absence produces no error, so nothing will remind you.",
          "Then watch the business contact mailbox for the 2FA mail."
        ],
        "failureLooksLike": "The brand verifies and looks healthy. No vet was ordered, every campaign is refused, and nothing anywhere reports a failure — because nothing failed."
      }
    },
    {
      "id": "BRD-226",
      "slug": "brd-226",
      "title": "The 2FA PIN must be completed inside the vet's window",
      "statement": "The business contact must complete the Authentication+ 2FA PIN within 30 days of the vet being submitted, or the vet must be re-submitted.",
      "rationale": "The window belongs to the vet rather than to the email, and it runs whether or not anyone saw the message — so a vet ordered before a quiet period expires quietly, and the fee goes with it. Public companies, whose contact is usually a senior person with a filtered mailbox, are the ones this catches.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the Authentication+ 2FA state",
      "severity": "BLOCKING",
      "detectability": [
        "UNDETECTABLE_PRE_SUBMISSION"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "TCR",
        "Twilio"
      ],
      "codes": [
        {
          "provider": "TCR",
          "code": "565",
          "remediable": true
        },
        {
          "provider": "Twilio",
          "code": "21737",
          "remediable": true
        }
      ],
      "applicability": {
        "entityTypes": [
          "PUBLIC_PROFIT"
        ]
      },
      "applicabilityText": "Applies when the brand is a public company.",
      "universal": false,
      "remediation": "Tell the named contact the mail is coming, before it is sent, and get their confirmation that they have completed the PIN. Track the 30-day deadline from the order date rather than from the mail date. Done when the brand reports Authentication+ active.",
      "notes": "The window is 30 days for the vet and 7 for the emailed link inside it (BRD-227); both are live and neither is visible to us. What the user has to do is own the deadline themselves — brief the contact before ordering, and chase inside the first week rather than the fourth.",
      "catalogIds": [
        "OPS-306"
      ],
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Has the named contact confirmed to you, in words, that they completed the PIN?",
        "howToCheck": [
          "Brief the contact before the vet is ordered, not after the mail is sent.",
          "Track the 30-day deadline from the order date, not from the mail date, and chase inside the first week rather than the fourth.",
          "Done when the brand itself reports Authentication+ active."
        ],
        "failureLooksLike": "A vet ordered before a quiet period expires quietly, taking the fee with it. The contact is usually a senior person with a filtered mailbox who never saw the message."
      }
    },
    {
      "id": "BRD-227",
      "slug": "brd-227",
      "title": "The emailed verification link expires after a week",
      "statement": "The Authentication+ verification link and PIN expire after seven days and must be re-requested.",
      "rationale": "Two different clocks run on the same vet: thirty days for the vet, seven for the mail inside it — so the link dies three weeks before the vet does, and a contact who returns from leave to find the message finds a link that no longer works. Requesting a fresh one is simple and nothing tells you that it is what you need.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the Authentication+ email link",
      "severity": "HIGH",
      "detectability": [
        "UNDETECTABLE_PRE_SUBMISSION"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "AWS",
        "Vonage",
        "Telnyx",
        "Aegis"
      ],
      "applicability": {
        "entityTypes": [
          "PUBLIC_PROFIT"
        ]
      },
      "applicabilityText": "Applies when the brand is a public company.",
      "universal": false,
      "remediation": "Re-request the verification mail rather than waiting on the old one, and have the contact complete it the same day it arrives. Done when the PIN is accepted and the brand reports Authentication+ active.",
      "notes": "The seven-day figure comes from the CPaaS documentation and is marked UNVERIFIED against a secondary source in the research; the thirty-day vet window (BRD-226) is TCR's own and is firm. What the user has to do is treat the link as short-lived whichever number is right: request it when the contact is available, not before.",
      "catalogIds": [
        "OPS-307"
      ],
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Will the contact be available to complete the PIN the same day the mail arrives?",
        "howToCheck": [
          "Request the verification mail when the contact is at their desk — the link is short-lived, roughly seven days inside a thirty-day vet window.",
          "If they return from leave to a dead link, re-request a fresh mail rather than waiting on the old one. Nothing tells you that is what you need."
        ],
        "failureLooksLike": "The link dies three weeks before the vet does. The contact finds the message, clicks it, and gets an error that suggests the whole vet has failed."
      }
    },
    {
      "id": "BRD-228",
      "slug": "brd-228",
      "title": "Do not queue a second Authentication+ vet behind a pending one",
      "statement": "A second Authentication+ vet must not be submitted while one is pending.",
      "rationale": "The second order is refused rather than queued, so the natural response to a vet that seems stuck — order another one — costs a fee and achieves nothing. It seems stuck because the 2FA has not been answered yet, which is a different problem with a different fix.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the Authentication+ vet queue",
      "severity": "MEDIUM",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR"
      ],
      "codes": [
        {
          "provider": "TCR",
          "code": "525",
          "remediable": true
        }
      ],
      "applicability": {
        "entityTypes": [
          "PUBLIC_PROFIT"
        ]
      },
      "applicabilityText": "Applies when the brand is a public company.",
      "universal": false,
      "remediation": "Check whether the 2FA mail has been answered before ordering anything. If the link has expired, re-request it (BRD-227); if the window has passed entirely, the existing vet has to fail before a new one can be placed. Done when only one Authentication+ vet is in flight.",
      "example": "One Authentication+ vet in flight — chase the 2FA mail rather than placing a second order",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-229",
      "slug": "brd-229",
      "title": "An unanswered 2FA is not an appealable failure",
      "statement": "An Authentication+ failure caused by an unanswered 2FA email must be resolved with a new vet rather than an appeal.",
      "rationale": "An appeal asks a reviewer to look again at a decision, and there was no decision here — the examination never completed because nobody answered the mail. The appeal is refused, the time is lost, and the vet still has to be re-ordered at the end of it. Appealing is the natural instinct because the outcome reads as a failure.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the Authentication+ failure reason",
      "severity": "MEDIUM",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR"
      ],
      "applicability": {
        "entityTypes": [
          "PUBLIC_PROFIT"
        ]
      },
      "applicabilityText": "Applies when the brand is a public company.",
      "universal": false,
      "remediation": "Order a new Authentication+ vet, with the contact briefed and available this time. Save the appeal for a vet that ran and reached a conclusion you disagree with. Done when a fresh vet is in flight rather than an appeal.",
      "example": "A new Authentication+ order — not an appeal, where the failure reason is an unanswered or expired 2FA",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-230",
      "slug": "brd-230",
      "title": "Identity-plus vetting is for public companies only",
      "statement": "An Authentication+ vet must not be ordered for a brand that is not PUBLIC_PROFIT.",
      "rationale": "Authentication+ is the two-factor confirmation designed for listed companies, and the registry refuses the order for any other entity type rather than downgrading it to something available. Teams order it because it is the strongest-sounding option on the list, and the fee is taken before the refusal.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the vet order + brand.entity_type",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR"
      ],
      "codes": [
        {
          "provider": "TCR",
          "code": "592",
          "remediable": true
        }
      ],
      "applicability": {
        "excludeEntityTypes": [
          "PUBLIC_PROFIT"
        ]
      },
      "applicabilityText": "Applies when the brand is NOT a public company.",
      "universal": false,
      "remediation": "Order a standard vet instead — it is the one that raises throughput for a private, non-profit or government brand. Authentication+ is not a higher tier of the same thing; it is a different verification for a different entity type.",
      "example": "vetting class: STANDARD for a PRIVATE_PROFIT brand — not AUTHPLUS",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-231",
      "slug": "brd-231",
      "title": "Identity information is frozen once Authentication+ completes",
      "statement": "After Authentication+ verification completes, brand identity information cannot be changed; a new brand must be created instead.",
      "rationale": "The completed verification is bound to the identity it examined, and the registry will not let that identity move underneath it — so an edit is refused rather than applied, and the only route to a corrected record is a new brand and a new verification. Discovering that after the campaigns are live is the expensive version, because they have to be rebuilt under the new brand.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the identity fields after Authentication+",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "TCR"
      ],
      "applicability": {
        "entityTypes": [
          "PUBLIC_PROFIT"
        ]
      },
      "applicabilityText": "Applies when the brand is a public company.",
      "universal": false,
      "remediation": "Get the identity fields right before ordering Authentication+ — the legal name in particular, since that is the one people correct later. Where a change is genuinely required afterwards, plan a new brand and the migration of every campaign under it.",
      "notes": "The freeze is enforced at the registry. What the user has to do is treat the Authentication+ order as the point of no return for the identity fields, and run the checks in BRD-002, BRD-003 and BRD-093 before placing it rather than after.",
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Are the identity fields — legal name above all — confirmed correct before you place the Authentication+ order?",
        "howToCheck": [
          "Run the identity checks first: the IRS name match, the EIN, and the address against the registration record.",
          "Treat the Authentication+ order as the point of no return: afterwards the identity cannot be edited, only rebuilt as a new brand with every campaign migrated under it."
        ],
        "failureLooksLike": "A legal name is corrected after the vet completes. The edit is refused rather than applied, and the only route to a right record is a new brand and a rebuild of the live campaigns."
      }
    },
    {
      "id": "BRD-232",
      "slug": "brd-232",
      "title": "Only three registration shapes may skip the automatic vet",
      "statement": "The skip-automatic-vetting flag may be set only for Low-Volume Standard registrations, 527 political organisations, and Campaign-Verify-registered brands.",
      "rationale": "The flag suppresses the secondary vet that would otherwise run, and it exists for the three cases where that vet is either unavailable or already discharged by another artefact. Setting it anywhere else does not save a fee — it produces a brand that skipped its verification and lands at the lowest throughput with no finding to explain why.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.skip_automatic_sec_vet",
      "severity": "HIGH",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Twilio"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Leave the flag unset unless the brand is Low-Volume Standard, a 527 organisation, or registered through Campaign Verify. If it was set to avoid a fee, clear it and accept the automatic vet — the throughput it buys is worth more than the fee it costs.",
      "example": "skip_automatic_sec_vet: false — unless brand_class is LOW_VOLUME_STANDARD, 527 or CAMPAIGN_VERIFY",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-233",
      "slug": "brd-233",
      "title": "Some providers require vetting for every use case above the lowest tier",
      "statement": "At least one provider requires standard or enhanced brand vetting for any use case beyond the lowest-volume mixed tier.",
      "rationale": "Where this applies, vetting stops being an upgrade and becomes a precondition for the use case itself — a marketing campaign simply cannot be registered without it. It is not visible in any field validation, so a team that budgeted for registration and not for vetting discovers the gap at the point the campaign is refused.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the vet record + campaign.use_case",
      "severity": "BLOCKING",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Vonage"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Check whether your provider gates use cases on vetting before quoting a customer, and order the vet as part of onboarding rather than as a later upgrade. Done when a vet is held before the campaign is submitted on a provider that requires one.",
      "notes": "Conditional on the submission target and stated by Vonage explicitly. What the user has to establish is whether their own provider imposes it — the answer is in the onboarding terms rather than in an error code, and finding it out afterwards costs the campaign schedule rather than the fee.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Have you checked whether your provider gates use cases on vetting, before quoting the customer?",
        "howToCheck": [
          "Read the provider's onboarding terms for a vetting precondition on anything above the lowest-volume mixed tier — it produces no field validation error.",
          "Where it applies, order the vet as part of onboarding rather than as a later upgrade."
        ],
        "failureLooksLike": "A team budgets for registration and not for vetting, and finds the gap when the marketing campaign is refused — with the schedule, not the fee, as the thing that is lost."
      }
    },
    {
      "id": "BRD-234",
      "slug": "brd-234",
      "title": "Vet before the campaign, not after the volume disappoints",
      "statement": "External vetting should be ordered before registering a campaign that needs material volume.",
      "rationale": "An unvetted brand starts at the bottom carrier tier — a couple of thousand messages a day — and the tier is what the campaign inherits at registration. Ordering the vet afterwards works, but the launch has already been scheduled against throughput the brand does not have, and the vet takes days. The cost of getting this wrong is a missed send date rather than a rejection, which is why nothing flags it.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the vet record",
      "severity": "HIGH",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Telnyx",
        "T-Mobile"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Decide the daily volume the programme needs, then order the vet if it is above the unvetted floor of roughly 2,000 messages a day. Do it before the campaign is registered, and allow several days for the result.",
      "notes": "Whether a vet was ordered is a fact about the account rather than about the registration, so this reports UNCLEAR rather than guessing. What the user has to do is the arithmetic: list size against the unvetted daily cap, and if the first exceeds the second, the vet is a prerequisite rather than an upgrade.",
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Does the volume this programme needs exceed the unvetted daily floor of roughly 2,000 messages a day?",
        "howToCheck": [
          "Do the arithmetic: list size and send frequency against the unvetted cap.",
          "If the first exceeds the second, order the vet before registering the campaign and allow several days for the result — the campaign inherits the brand's tier at registration."
        ],
        "failureLooksLike": "Nothing is rejected. The launch is scheduled against throughput the brand does not have, and the vet that would fix it takes days that the send date does not allow."
      }
    },
    {
      "id": "BRD-235",
      "slug": "brd-235",
      "title": "The daily carrier cap is an EIN-level allowance, pooled across CSPs",
      "statement": "The T-Mobile daily brand cap is an allowance against the tax ID, pooled across every campaign and every CSP that registered it, resetting at midnight Pacific.",
      "rationale": "Because the cap attaches to the EIN rather than to the brand, splitting traffic across two providers does not double it — the two routes draw from one bucket, and the second one starts failing when the first has used the allowance. Teams add a provider specifically to increase capacity and get no more messages delivered, with the failures landing on whichever route sent last.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "daily volume against brand.ein",
      "severity": "HIGH",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "T-Mobile",
        "TCR"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Plan volume against one allowance per tax ID, not per provider or per campaign, and reconcile sends across every route before scheduling a large day. The window resets at midnight Pacific, which is the boundary to schedule around.",
      "notes": "Absorbs OPS-118, which states the same pooling behaviour. Volume is not visible at registration time. What the user has to do is add up the traffic across every CSP that holds a brand on this EIN — including ones another team set up — because the cap does not care that they are separate accounts.",
      "catalogIds": [
        "OPS-118"
      ],
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Have you added up the daily traffic across every CSP and every campaign that shares this tax ID?",
        "howToCheck": [
          "List every provider holding a brand on this EIN — including accounts another team set up. The cap does not care that they are separate accounts.",
          "Reconcile the total against one allowance before scheduling a large day, and schedule around the midnight Pacific reset."
        ],
        "failureLooksLike": "A second provider is added specifically to increase capacity, and no more messages are delivered. Both routes draw on one bucket, and the failures land on whichever sent last."
      }
    },
    {
      "id": "BRD-237",
      "slug": "brd-237",
      "title": "Short-code assignment needs a successful vetting status",
      "statement": "A successful vetting status on the brand and the content provider is required to be assigned a short code or to extend a lease.",
      "rationale": "Short codes are leased on a longer cycle than 10DLC brands are vetted, so a lease renewal can arrive when the vet has lapsed — and the renewal is refused for a reason that has nothing to do with the code or the programme running on it. Losing a short code is disproportionately expensive, because the number is printed on things.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the vetting status",
      "severity": "BLOCKING",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "CTIA",
        "Infobip"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Check the vetting status well before a lease renewal date and re-vet if it has lapsed. Done when a current successful vet is in place on both the brand and the content provider ahead of the renewal.",
      "effectiveFrom": "2025-03-31",
      "notes": "A short-code path requirement, recorded here because the vet is a brand-level artefact. What the user has to do is track the lease date against the vet date themselves — nothing connects the two, and the renewal window is short.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Is a current successful vet in place on both the brand and the content provider, ahead of the short-code lease renewal date?",
        "howToCheck": [
          "Put the lease renewal date and the vet date side by side. Nothing connects the two automatically, and the renewal window is short.",
          "Re-vet before the renewal if the vet has lapsed."
        ],
        "failureLooksLike": "The renewal is refused for a reason that has nothing to do with the code or the programme on it — and the number is printed on packaging, vehicles and signage."
      }
    },
    {
      "id": "BRD-238",
      "slug": "brd-238",
      "title": "Re-vet annually",
      "statement": "Brand vetting must be renewed each year, with the 2FA verification completed again to the brand email on file.",
      "rationale": "A vet certifies the business as it was, and businesses move, rename and change hands — so the certification is time-boxed. The renewal goes to the email on file, which is often a person who has left, and the first sign that it lapsed is throughput dropping back to the unvetted tier.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the vet age",
      "severity": "HIGH",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Aegis",
        "CTIA"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Diary the re-vet a month before the anniversary and confirm the brand email still reaches somebody first. Done when the renewal completes before the existing vet expires, rather than after throughput drops.",
      "notes": "Flagged UNVERIFIED in the research — the annual cadence comes from a secondary source rather than from CTIA directly, so treat it as the prudent assumption rather than a published deadline. What the user has to do either way is keep the brand email monitored, since that is where the renewal lands.",
      "phase": "post",
      "automated": false,
      "attestation": {
        "question": "Do you know the vet's anniversary date, and does the brand email still reach somebody who will act on the renewal?",
        "howToCheck": [
          "Diary the re-vet a month before the anniversary.",
          "Check the brand email on file first — it is often a person who has left, and that is where the renewal and its 2FA land.",
          "Treat the annual cadence as the prudent assumption; the research flags it as a secondary source rather than a published deadline."
        ],
        "failureLooksLike": "The first sign the vet lapsed is throughput dropping back to the unvetted tier, weeks after the renewal mail went to a mailbox nobody reads."
      }
    },
    {
      "id": "BRD-241",
      "slug": "brd-241",
      "title": "Political vetting is satisfied by exactly one recognised artefact",
      "statement": "A political brand must hold exactly one of: a Campaign Verify token, an Aegis political vet, or verified 501(c)(3/4/5/6) status.",
      "rationale": "The three routes are alternatives rather than a checklist, and they are not interchangeable in cost or lead time — Campaign Verify is free and slow, an Aegis vet is paid and faster, and the tax-exempt route is instant if you already hold the status. Choosing the wrong one for the time available is how political campaigns miss their own dates.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the political vetting artefact",
      "severity": "BLOCKING",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "TCR",
        "Infobip"
      ],
      "codes": [
        {
          "provider": "TCR",
          "code": "509",
          "remediable": true
        },
        {
          "provider": "Infobip",
          "code": "9001",
          "remediable": true
        }
      ],
      "applicability": {
        "useCases": [
          "POLITICAL"
        ]
      },
      "applicabilityText": "Applies when the use case is POLITICAL.",
      "universal": false,
      "remediation": "Pick the route that fits the calendar: 501(c)(4), (5) or (6) status qualifies immediately at some providers; a Campaign Verify token needs an FEC or state filing and takes days; an Aegis political vet is bought and couriers a PIN. Start whichever one you choose weeks before the send date.",
      "notes": "Which artefacts a brand holds is not on the registration. What the user has to do is choose the route deliberately and start it early — the Campaign Verify path in particular depends on a filing reference and on post, neither of which can be hurried.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Have you chosen one of the three political routes deliberately, and started it far enough ahead of the send date?",
        "howToCheck": [
          "Pick by calendar, not by cost: 501(c)(4), (5) or (6) status qualifies immediately at some providers; a Campaign Verify token needs an FEC or state filing and takes days; an Aegis political vet is bought and couriers a PIN.",
          "Start weeks before the send date. The Campaign Verify path depends on a filing reference and on post, and neither can be hurried."
        ],
        "failureLooksLike": "The cheapest route is chosen in the last fortnight of a cycle. It is also the slowest, and the campaign misses its own date."
      }
    },
    {
      "id": "BRD-242",
      "slug": "brd-242",
      "title": "A tax-exempt organisation must not order a political vet",
      "statement": "A political vet must not be requested or imported for a brand that already holds 501(c)(3), (4), (5) or (6) status.",
      "rationale": "The tax-exempt status is itself one of the three qualifying artefacts, so ordering a vet on top of it is disallowed rather than redundant — the request is refused. It is a natural mistake because the vet looks like the thorough option, and nothing in the ordering flow says the status you already hold has made you ineligible for it.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.tax_exempt_status + the political vet order",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR"
      ],
      "codes": [
        {
          "provider": "TCR",
          "code": "541",
          "remediable": true
        }
      ],
      "applicability": {
        "entityTypes": [
          "NON_PROFIT"
        ]
      },
      "applicabilityText": "Applies when the brand is a non-profit.",
      "universal": false,
      "remediation": "Rely on the tax-exempt status you already hold and do not order or import a political vet. Make sure the status is recorded as an attribute on the brand rather than only claimed on the form — BRD-263 is the appeal route if the registry did not set it.",
      "example": "tax_exempt_status: 501(c)(4) with no political vet ordered — the status is the qualifying artefact",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-243",
      "slug": "brd-243",
      "title": "A 527 organisation needs a token and its filing reference on record",
      "statement": "A 527 political organisation must hold a Campaign Verify token, and must record the FEC ID or state filing URL used to obtain it.",
      "rationale": "The token proves the organisation was verified; the filing reference proves which organisation it was verified as. Keeping only the token leaves a claim nobody can retrace when a carrier asks, and political programmes attract exactly that kind of question — usually in the last fortnight before an election.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the Campaign Verify token + the filing reference",
      "severity": "BLOCKING",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EVIDENCE",
      "authorities": [
        "Infobip",
        "Campaign Verify",
        "TCR"
      ],
      "codes": [
        {
          "provider": "Infobip",
          "code": "9001",
          "remediable": true
        }
      ],
      "applicability": {
        "useCases": [
          "POLITICAL"
        ]
      },
      "applicabilityText": "Applies when the use case is POLITICAL.",
      "universal": false,
      "remediation": "Obtain the Campaign Verify token, and store the FEC committee ID or the state filing URL beside it in the same record. Done when both can be produced together in a single reply to a carrier query.",
      "notes": "Neither artefact is visible in a registration. What the user has to do is keep them together at the point they are obtained — the filing reference is easy to find while you are applying and surprisingly hard to reconstruct six months later.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Are the Campaign Verify token and the FEC committee ID or state filing URL stored together, retrievable in one reply?",
        "howToCheck": [
          "Record the filing reference beside the token at the moment you obtain it — it is easy to find while applying and surprisingly hard to reconstruct six months later.",
          "Test it: ask whoever answers carrier queries to produce both, now."
        ],
        "failureLooksLike": "Only the token was kept. It proves an organisation was verified and not which one, and the question arrives in the last fortnight before an election."
      }
    },
    {
      "id": "BRD-244",
      "slug": "brd-244",
      "title": "A political token imports only onto an eligible, campaign-free brand",
      "statement": "A Campaign Verify token may be imported only onto a US-based non-profit brand without 501(c) status, and only while the brand has no active campaigns.",
      "rationale": "Two independent conditions, and the second is the one that catches people: the import is refused once campaigns exist, so a brand that registered a campaign first has to unwind it to complete the verification. Political teams reliably register the campaign first, because the campaign is the thing they are actually trying to launch.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the Campaign Verify import target",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR"
      ],
      "codes": [
        {
          "provider": "TCR",
          "code": "541",
          "remediable": true
        },
        {
          "provider": "TCR",
          "code": "540",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Import the token onto the brand before registering any campaign under it. If campaigns already exist, deactivate them, complete the import, then register them again. Done when the import lands on a US non-profit brand with no 501(c) status and no active campaigns.",
      "example": "entity_type: NON_PROFIT · country: US · tax_exempt_status: (none) · active campaigns: 0 — then import the token",
      "pitfalls": [
        "Deactivating a campaign to unblock the import means re-registering it afterwards, and the second registration is reviewed like any other."
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-246",
      "slug": "brd-246",
      "title": "A political token is used once and once only",
      "statement": "Each Campaign Verify token is single-use and unique to one brand and CSP; a second use requires a reissue or a fresh political vet.",
      "rationale": "Standard vetting tokens can be spread across duplicate brand instances (BRD-218) and political ones cannot, so an operator who learned the first behaviour applies it to the second and the reuse is refused. Getting another token is not a self-service action — it means going back to Campaign Verify — which is why this costs days rather than minutes.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the Campaign Verify token",
      "severity": "BLOCKING",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Twilio",
        "TCR"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "21722",
          "remediable": true
        },
        {
          "provider": "TCR",
          "code": "543",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Use each token on exactly one brand at one CSP. Where the same organisation registers through two providers, request a second token from Campaign Verify rather than importing the first one twice — and request it before you need it.",
      "notes": "Absorbs OPS-320, which contrasts single-use political tokens with the multi-use standard tokens in BRD-218. Whether a token has already been consumed is registry state we cannot see. What the user has to track is which brand each token went to, because the refusal on the second import does not say where the first one was used.",
      "catalogIds": [
        "OPS-320"
      ],
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Has this Campaign Verify token been used on any other brand or at any other CSP?",
        "howToCheck": [
          "Keep a record of which brand each token went to. The refusal on a second import does not say where the first one was used.",
          "Registering the same organisation through two providers means requesting a second token from Campaign Verify — before you need it, since it is not self-service."
        ],
        "failureLooksLike": "Standard vetting tokens can be spread across duplicate brand instances, so an operator applies the same habit to a political one. The reuse is refused and getting another costs days."
      }
    },
    {
      "id": "BRD-247",
      "slug": "brd-247",
      "title": "Check the token has not expired before importing it",
      "statement": "A Campaign Verify token must be checked for expiry before it is imported.",
      "rationale": "Tokens are obtained when the paperwork is ready and imported when the campaign is, and those can be months apart — so an expired token is the normal consequence of an organised team working ahead. The import is refused, and the replacement has to come from Campaign Verify rather than from the provider.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the token expiry",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Twilio"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "21722",
          "remediable": true
        },
        {
          "provider": "Twilio",
          "code": "30713",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Read the expiry date off the token before importing, and request a fresh one if it has passed or is close. Done when the token in hand is current at the moment of import, not at the moment it was issued.",
      "example": "token expiry: 2026-11-30, imported 2026-08-14 — current at the time of import",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-248",
      "slug": "brd-248",
      "title": "One political import at a time",
      "statement": "A second Campaign Verify import must not be submitted while one is in progress.",
      "rationale": "The second request is refused rather than queued, and because a political import is slow it looks stalled long before it is — so resubmitting is the obvious thing to do and it makes the situation worse rather than better. On a dated campaign, the lost cycle is the actual cost.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the Campaign Verify import queue",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Twilio"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "21723",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Let the in-flight import finish before submitting anything else against this brand. If it has genuinely stalled, ask the provider to check its state rather than resubmitting — a second request is refused and does not replace the first.",
      "example": "One political import in flight — check its state rather than submitting a second",
      "notes": "Absorbs OPS-321, which states the same in-flight restriction and the request fields it applies to.",
      "catalogIds": [
        "OPS-321"
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-249",
      "slug": "brd-249",
      "title": "The political filing email must match the registration",
      "statement": "For an Aegis political vet, the filing email must exactly match the email on the political registration, and must not be a consumer domain.",
      "rationale": "The vet confirms that the person filing is the one named in the public political registration, and the email is the identifier it compares — so a campaign manager who files with their own address fails a check about somebody else's identity. Consumer domains are refused outright, which catches small local campaigns that genuinely run from a personal mailbox.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the political filing email",
      "severity": "BLOCKING",
      "detectability": [
        "AI_FORM",
        "EXTERNAL_DATA"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "Aegis"
      ],
      "applicability": {
        "useCases": [
          "POLITICAL"
        ]
      },
      "applicabilityText": "Applies when the use case is POLITICAL.",
      "universal": false,
      "remediation": "Use the exact email address on the FEC or state filing. If that filing carries a consumer address, update the filing first — the vet compares against the register, so the register is what has to change.",
      "example": "filing email: press@riversideshelter.org, matching the address on the committee filing — not a personal gmail address",
      "notes": "Whether the address matches the political register needs the register itself, which we do not hold. What the judgement can see is whether a consumer domain was used, which is the half that is refused outright. The user has to compare the address against their own filing before ordering the vet, because the fee is spent on the mismatch.",
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Is the filing email on the vet order character-identical to the email on the FEC or state political registration, and is it not a consumer domain?",
        "howToCheck": [
          "Open your own political filing and copy the address from it.",
          "Where the filing itself carries a personal address, update the filing first — the vet compares against the register, so the register is what has to change."
        ],
        "failureLooksLike": "A campaign manager files with their own address. The vet is checking somebody else's identity, the fee is spent on the mismatch, and small local campaigns that genuinely run from a personal mailbox are refused outright."
      }
    },
    {
      "id": "BRD-250",
      "slug": "brd-250",
      "title": "The political vetting contact must be named in the registration",
      "statement": "The contact name on an Aegis political vet must match an authorised name in the political registration — not the CSP's or the aggregator's.",
      "rationale": "The vet verifies a named individual against the public filing, so the CSP contact who is doing the paperwork is exactly the wrong name to use. It is the natural one to use, because they are the person completing the form, and the failure comes back as an identity mismatch that reads as though the organisation itself was not recognised.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the political vetting contact name",
      "severity": "BLOCKING",
      "detectability": [
        "HUMAN"
      ],
      "failureClass": "TERMINAL_EVIDENCE",
      "authorities": [
        "TCR",
        "Aegis"
      ],
      "applicability": {
        "useCases": [
          "POLITICAL"
        ]
      },
      "applicabilityText": "Applies when the use case is POLITICAL.",
      "universal": false,
      "remediation": "Take the contact name from the political filing — the treasurer or the authorised representative named there — and use it on the vet, even if that person is not the one submitting. Confirm they are available to receive the couriered PIN.",
      "notes": "The authorised names are in the public filing rather than in the registration. What the user has to do is open their own FEC or state filing and copy the name from it, and warn that person that a courier is coming.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Is the contact name on the vet an authorised name from the political filing, and does that person know a courier is coming?",
        "howToCheck": [
          "Open the FEC or state filing and copy the treasurer's or authorised representative's name from it — not the name of whoever is completing the paperwork.",
          "Warn that person that a couriered PIN is on its way and confirm they will be there to receive it."
        ],
        "failureLooksLike": "The CSP contact doing the form uses their own name. The failure returns as an identity mismatch that reads as though the organisation itself was not recognised."
      }
    },
    {
      "id": "BRD-251",
      "slug": "brd-251",
      "title": "A federal donation programme needs a current FEC registration",
      "statement": "A federal candidate, committee or party running a donation programme must be currently registered with the FEC.",
      "rationale": "Political donation messaging carries the highest scrutiny of any use case, and a current FEC registration is the baseline that makes the rest of it reviewable. \"Currently\" is the load-bearing word: registrations lapse between cycles, and a committee reactivating for a new cycle can be messaging weeks before its filing catches up.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the FEC registration",
      "severity": "BLOCKING",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "CTIA"
      ],
      "applicability": {
        "useCases": [
          "POLITICAL"
        ]
      },
      "applicabilityText": "Applies when the use case is POLITICAL.",
      "universal": false,
      "remediation": "Confirm the committee's FEC registration is current before any donation messaging goes out, and keep the committee ID with the brand record. State and local candidates use the equivalent state filing.",
      "notes": "FEC status is public but not something we query. What the user has to do is check their own committee in the FEC database and confirm it is active for the current cycle — a lapsed registration is the common case at the start of a cycle, and it is fixed by filing rather than by anything in the messaging setup.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Is the committee's FEC registration active for the current cycle, today?",
        "howToCheck": [
          "Look the committee up in the FEC database and confirm the registration is current, not merely present. State and local candidates check the equivalent state filing.",
          "Keep the committee ID with the brand record."
        ],
        "failureLooksLike": "A committee reactivating for a new cycle is messaging weeks before its filing catches up. \"Currently registered\" is the load-bearing phrase, and it is fixed by filing rather than by anything in the messaging setup."
      }
    },
    {
      "id": "BRD-254",
      "slug": "brd-254",
      "title": "Appeal only a vet that has finished",
      "statement": "An appeal may be filed only against a vet in a final state — never against one still pending.",
      "rationale": "A pending vet has not decided anything, so an appeal against it is refused on entry and the attempt is wasted. The reason people file early is that a vet in progress is indistinguishable from one that is stuck, and the appeal form is available the whole time.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the vet state",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR"
      ],
      "codes": [
        {
          "provider": "TCR",
          "code": "592",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Wait for the vet to reach ACTIVE, COMPLETE, FAILED or EXPIRED before filing. If it looks stuck, the cause is usually an unanswered 2FA rather than a queue — chase that instead. Done when the appeal is filed against a vet that has actually concluded.",
      "example": "appeal filed against a vet in FAILED state — not against one still PENDING",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-255",
      "slug": "brd-255",
      "title": "Choose an appeal category valid for this entity type",
      "statement": "At least one appeal category must be selected, and it must be one that is valid for the brand's entity type.",
      "rationale": "Categories route the appeal to the reviewer who can decide it, so one that does not apply to this entity type has nowhere to go and the filing is rejected rather than reassigned. The list is offered in full regardless of entity type, which is precisely why the wrong one gets chosen.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "appeal.appeal_categories",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR"
      ],
      "codes": [
        {
          "provider": "TCR",
          "code": "559",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Pick the category that names what you are contesting, and check it applies to your entity type — tax-exempt status only for a non-profit, government status only for a government body. Done when at least one valid category is selected.",
      "example": "appeal_categories: [\"TAX_EXEMPT_STATUS\"] on a NON_PROFIT brand",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-256",
      "slug": "brd-256",
      "title": "The low-score category does not apply to an identity appeal",
      "statement": "The LOW_SCORE appeal category is valid only for an external vetting appeal, never for an identity-status appeal.",
      "rationale": "Identity and score are decided by different processes, so an identity appeal filed under LOW_SCORE reaches a reviewer who cannot act on it and is refused. It is an easy mistake because a failed identity check and a poor score both present to the user as \"the brand did not pass\", and LOW_SCORE is the category that sounds like it covers both.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "appeal.appeal_categories",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR"
      ],
      "codes": [
        {
          "provider": "TCR",
          "code": "559",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "For an identity appeal, choose the category naming the field in dispute — business name, address or contact. Keep LOW_SCORE for appealing the result of an external vet. Done when the category matches which of the two decisions is being contested.",
      "example": "appeal_categories: [\"BUSINESS_NAME\"] on an identity appeal — LOW_SCORE only on a vetting appeal",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-257",
      "slug": "brd-257",
      "title": "Keep the appeal explanation inside its limit",
      "statement": "The appeal explanation must be no longer than 1,024 characters.",
      "rationale": "The field is silently bounded, and an appeal is exactly the moment someone writes at length — the whole history of the registration, every correction attempted. The submission is rejected on the length rather than truncated, so the work is lost along with the attempt.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "appeal.explanation",
      "severity": "MEDIUM",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR"
      ],
      "codes": [
        {
          "provider": "TCR",
          "code": "501",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Write the explanation as three sentences: what was decided, what is wrong with it, and what the attached document proves. Put the detail in the attachments, which is where a reviewer looks anyway. Done when the field is under 1,024 characters.",
      "example": "explanation: \"The brand was refused as unverified. The legal name on the registration matches the attached CP-575 exactly, including the comma before LLC. The address matches the same letter. Please re-run verification against the attached document.\"",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-258",
      "slug": "brd-258",
      "title": "Respect the appeal attachment limits",
      "statement": "An appeal may carry at most ten attachments, each no larger than 10 MB, and no more than 30 MB in total.",
      "rationale": "Three separate limits apply at once and only the one you hit is reported, so an appeal built from phone photographs of documents fails on total size after being trimmed to ten files. Every attempt costs a cycle, and appeals are usually filed under time pressure with a campaign already blocked.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the appeal attachments",
      "severity": "MEDIUM",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR"
      ],
      "codes": [
        {
          "provider": "TCR",
          "code": "544",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Combine the pages of each document into one PDF and compress scans to text-readable rather than photographic quality. Two or three well-made PDFs beat ten photographs and land inside every limit at once. Done when there are ten or fewer files, none over 10 MB, and 30 MB in total.",
      "example": "attachments: cp575.pdf (1.2 MB), state-registration.pdf (0.8 MB) — two documents, all pages in each",
      "notes": "Absorbs OPS-328, which states the same attachment limits alongside the explanation length in BRD-257. Combining pages into one PDF also discharges BRD-260, which requires every page of a multi-page document to be attached.",
      "catalogIds": [
        "OPS-328"
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-260",
      "slug": "brd-260",
      "title": "Attach every page of a multi-page document",
      "statement": "Where a supporting document runs to several pages, all of them must be attached — partial submissions are rejected.",
      "rationale": "People attach the page with the answer on it, because that is the page that matters to them. The reviewer needs the document to be self-evidently the whole document — an EIN letter is three pages and a single page of it could have come from anywhere — so a partial submission is refused without the argument being read.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the appeal attachments",
      "severity": "HIGH",
      "detectability": [
        "HUMAN",
        "UNDETECTABLE_PRE_SUBMISSION"
      ],
      "failureClass": "TERMINAL_EVIDENCE",
      "authorities": [
        "TCR"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Scan the document end to end and attach it as one PDF, including the pages that look like boilerplate. Done when the attachment has the same number of pages as the paper document.",
      "notes": "Only the person holding the document knows how many pages it has. What the user must do is check the page count before attaching — and combining the pages into a single PDF also keeps the file count inside the limits in BRD-258.",
      "catalogIds": [
        "OPS-327"
      ],
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Does the attachment have the same number of pages as the paper document in your hand?",
        "howToCheck": [
          "Count the pages of the original, then count the pages of the PDF you are attaching.",
          "Scan end to end and combine into a single PDF, boilerplate pages included — that also keeps the file count inside the attachment limits."
        ],
        "failureLooksLike": "The page with the answer on it is attached alone. An EIN letter runs to three pages, and one page of it could have come from anywhere, so the appeal is refused without the argument being read."
      }
    },
    {
      "id": "BRD-261",
      "slug": "brd-261",
      "title": "Only federal tax documentation counts in an appeal",
      "statement": "Appeals must rely on federal-level tax documentation; state-level documents are not accepted.",
      "rationale": "Verification runs against federal records, so a state filing — however official — does not corroborate the thing being checked and the appeal fails with the document attached. State certificates are the ones businesses have to hand, which is why they are the ones that get sent.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the appeal attachments",
      "severity": "HIGH",
      "detectability": [
        "HUMAN"
      ],
      "failureClass": "TERMINAL_EVIDENCE",
      "authorities": [
        "Twilio",
        "HighLevel"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Attach the IRS CP-575 or a 147C letter. If neither is to hand, request a 147C from the IRS Business & Specialty Tax Line before filing — it is free and it is the document the appeal actually needs.",
      "notes": "We cannot see which document is attached. What the user has to do is check the letterhead: a state incorporation certificate, a state tax registration or a good-standing certificate will not carry the appeal, and sending one costs a full cycle before anyone says so.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "Is the document you are attaching federal — a CP-575 or 147C — rather than a state filing?",
        "howToCheck": [
          "Read the letterhead. A state incorporation certificate, a state tax registration or a certificate of good standing will not carry the appeal.",
          "No federal letter to hand: request a 147C from the IRS Business & Specialty Tax Line before filing the appeal. It is free."
        ],
        "failureLooksLike": "The state certificate is the one the business has in a drawer, so it is the one that gets sent. The appeal fails with a perfectly official document attached, and a full cycle is lost before anyone says why."
      }
    },
    {
      "id": "BRD-263",
      "slug": "brd-263",
      "title": "Appeal a missing status attribute even on a verified brand",
      "statement": "A VERIFIED non-profit or government brand must still appeal where its tax-exempt or government attribute is missing.",
      "rationale": "Verification and the status attribute are separate outcomes, and only the second one opens the use cases and the throughput the classification exists for — so a brand can be VERIFIED, look entirely healthy, and still be treated as an ordinary commercial sender. Nobody appeals a brand that passed, which is exactly why this sits unnoticed for months.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the optional attributes + the appeal",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR"
      ],
      "applicability": {
        "entityTypes": [
          "NON_PROFIT",
          "GOVERNMENT"
        ]
      },
      "applicabilityText": "Applies when the brand is a non-profit and government.",
      "universal": false,
      "remediation": "Check the brand record for the tax-exempt or government attribute once verification completes. If it is missing, file an appeal in that category with the IRS determination letter or the authorising statute attached — do not re-register. Done when the attribute reads back on the brand.",
      "example": "tax_exempt_status: 501(c)(3) present on the brand record after verification — not merely claimed on the form",
      "notes": "Absorbs OPS-326, which states which identity statuses can be appealed and for which entity types. The check reads what the registration declares; whether the attribute was actually SET by the registry is something the user has to read off the brand record after verification, and this rule is the reminder to go and look.",
      "catalogIds": [
        "OPS-326"
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-267",
      "slug": "brd-267",
      "title": "Every brand field must be within its maximum length",
      "statement": "Each brand text field must be within the strictest cap its downstream targets enforce.",
      "rationale": "Over-long values are truncated or rejected depending on the provider, and Bandwidth applies the cap at provisioning rather than at vetting — so a brand can verify successfully and then fail when numbers are attached to it, which is the point at which nobody is looking at the brand record any more.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "all brand text fields",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Telnyx",
        "TCR",
        "Twilio",
        "Bandwidth"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Shorten the named field to its cap. Where a legal name genuinely exceeds 100 characters, use the first line of the IRS-registered name — that is what BRD-007 asks for anyway. Done when every field is inside its limit.",
      "example": "company_name: Acme Coffee Co, LLC — 19 of 100 characters",
      "notes": "Caps are the strictest across the documented targets, which is Telnyx for most fields: displayName, companyName, email, street, city, website ≤100; ein, phone, state ≤20; postalCode, stockSymbol ≤10; country exactly 2. TCR is looser on several, so a value inside these passes everywhere.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-268",
      "slug": "brd-268",
      "title": "Brand contact fields must contain no spaces",
      "statement": "The brand contact email and phone fields must contain no whitespace.",
      "rationale": "A trailing space survives a copy-paste and is invisible in the field, and the registry compares these values as strings — so the address that looks identical to the one on file does not match it. It is the defect users are least able to see, which is why it is worth catching mechanically rather than asking them to look again.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.email + brand.phone",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Telnyx",
        "TCR"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Strip every space from the email and phone fields, including leading and trailing ones. Done when neither value contains a space character anywhere.",
      "example": "email: support@acmecoffee.com · phone: +14155550134",
      "pitfalls": [
        "Pasting from a spreadsheet or a PDF is where the trailing space comes from, and the field will look correct in every screenshot you take of it."
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-269",
      "slug": "brd-269",
      "title": "No emoji in any brand field",
      "statement": "No brand field may contain an emoji or pictograph.",
      "rationale": "Brand fields are matched against tax and registry records, which hold plain text — an emoji guarantees the match fails, and several providers reject the payload outright. It arrives through display names copied from a social profile, where the emoji is part of how the brand presents itself.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "all brand text fields",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Telnyx",
        "TCR",
        "Twilio"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Remove the emoji from the named field. Keep it in your social profiles and your message content where it is fine — it is only the registry fields that must be plain. Done when every brand field is plain business text.",
      "example": "display_name: Acme Coffee — not \"Acme Coffee ☕\"",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-270",
      "slug": "brd-270",
      "title": "Placeholder values are not answers",
      "statement": "Required brand contact and address fields must not hold placeholder values such as N/A, TBD or none.",
      "rationale": "A form that will not submit without a value teaches people to type N/A, and the field is then populated and useless — worse than empty, because nothing downstream flags it as missing. Reviewers read it as a business unwilling to give its own address, which is a much less charitable reading than the one that is true.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand contact and address fields",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR",
        "AWS",
        "Bandwidth"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Replace the placeholder with the real value. Where you genuinely do not have one — a business with no suite number, say — leave the field empty rather than filling it with a word. Done when every populated field holds real data.",
      "example": "street: 1240 Mission St, Suite 400 — not \"N/A\" and not \"TBD\"",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-271",
      "slug": "brd-271",
      "title": "Brand content must be submitted in English",
      "statement": "Every brand text field must be submitted in English; non-English submissions are rejected as untranslatable.",
      "rationale": "Reviewers work in English and the registry offers no translation step, so a record in another script is not read strictly — it is returned. Businesses that trade bilingually submit their own language honestly, and the rejection reason (\"untranslatable\") gives no hint that the fix is to transliterate rather than to correct anything. The messages themselves may be in any language; it is only the registration that has to be readable.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "all brand text fields",
      "severity": "HIGH",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Bandwidth",
        "Infobip"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Re-enter the named fields in English, transliterating the legal name into the Latin alphabet exactly as it appears on the English-language registration document. Done when every brand field is in Latin script and a reviewer with no other language can read the record.",
      "example": "company_name: Acme Coffee Co, LLC · city: San Francisco — Latin script throughout, whatever language the messages themselves use",
      "pitfalls": [
        "Accented Latin characters are fine — José, Zürich, Ñ. It is a change of script, not of alphabet, that stops the record being readable."
      ],
      "notes": "Only the script half is mechanical, and that is all this check claims: it reports Cyrillic, Greek, Hebrew, Arabic, Devanagari, Thai, CJK and Hangul in a brand field. Whether Latin-script text is actually English — French, Spanish, German — is a judgement no predicate can make, and the rule deliberately does not pretend to. Emoji are BRD-269 and are excluded here so one defect is not reported twice.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-272",
      "slug": "brd-272",
      "title": "The end-business block must be complete, not partly filled",
      "statement": "On a toll-free verification, every end-business detail must be populated rather than a subset of them.",
      "rationale": "A partly filled end-business block is rejected as a whole rather than field by field, and the reviewer cannot tell an omission from a business that has no answer. It arrives from integrations that map whichever fields their own record happens to hold, so the gaps are wherever the source system was thin rather than wherever the business is.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the end-business block",
      "severity": "HIGH",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Bandwidth"
      ],
      "codes": [
        {
          "provider": "Bandwidth",
          "code": "TFV 1105",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Fill every end-business field before submitting: legal name, address, contact name, phone, email and website. Where a value is genuinely unknown, get it from the customer rather than leaving the field out — a partial submission costs a full review cycle.",
      "example": "company_name, street, city, state, postal_code, country, rep first/last name, phone, email and website — all populated",
      "notes": "Scoped to the toll-free path, where the end-business block is submitted as a unit and rejected as one. The equivalent completeness requirement for a 10DLC brand is spread across BRD-001, BRD-017, BRD-091 and BRD-102, each of which names its own field — so this rule does not repeat them.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-273",
      "slug": "brd-273",
      "title": "Contact, email, address and URL must each stand up on their own",
      "statement": "The representative, the email, the address and the website must each independently resolve or validate.",
      "rationale": "Verification does not average across the record: each identity component is checked separately, and one that cannot be resolved drags the whole submission rather than being outweighed by the four that could. Registrations assembled from several internal systems are where this bites, because each field is correct in its own system and one of them is stale.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.authorized_rep + brand.email + address + brand.website",
      "severity": "HIGH",
      "detectability": [
        "CRAWL",
        "EXTERNAL_DATA"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "Bandwidth"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Check each component against its own source before submitting: the representative against the company's own staff list, the email by sending a test, the address against the postal authority, the website by opening it in a private window. Done when all four resolve independently.",
      "example": "rep: Jane Doe, CEO · email: jane.doe@acmecoffee.com · address: 1240 Mission St, Suite 400, San Francisco, CA 94103 · website: https://acmecoffee.com",
      "notes": "The crawl settles the website and, where the site publishes them, the address and the contact details. Whether the mailbox accepts mail and whether the address is deliverable are BRD-115 and BRD-095 and are external. What the user has to do is the four-step check in the remediation, because a component that fails here fails silently as a lowered score rather than as a named finding.",
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Have you checked all four identity components against their own sources — representative, email, address, website — rather than assuming the record is right because most of it is?",
        "howToCheck": [
          "Representative: against the company's own staff list.",
          "Email: by sending a test message from outside.",
          "Address: against the postal authority's standardised form.",
          "Website: by opening it in a private window, logged out."
        ],
        "failureLooksLike": "A registration assembled from four internal systems, each correct in its own system and one of them stale. Verification does not average — the stale one drags the whole submission, silently, as a lowered score."
      }
    },
    {
      "id": "BRD-274",
      "slug": "brd-274",
      "title": "RCS brand assets have exact dimension, size and format constraints",
      "statement": "An RCS logo must be 224×224 pixels and at most 50 KB, a banner 1440×448 and at most 200 KB, both JPEG or PNG, with at most 50 of each per brand.",
      "rationale": "The assets render inside the verified sender card on a phone, so the constraints are exact rather than advisory and the upload is refused rather than resized. Design teams export at the resolution their brand guidelines specify, which is invariably larger, and the rejection arrives as a numeric code after the artwork has been signed off.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.assets",
      "severity": "BLOCKING",
      "detectability": [
        "DETERMINISTIC"
      ],
      "failureClass": "RETRY_FIELD",
      "authorities": [
        "TCR"
      ],
      "codes": [
        {
          "provider": "TCR",
          "code": "546",
          "remediable": true
        },
        {
          "provider": "TCR",
          "code": "547",
          "remediable": true
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Export the logo at exactly 224×224 and the banner at exactly 1440×448, as PNG or JPEG, and compress each under its ceiling — 50 KB for the logo, 200 KB for the banner. Done when every asset matches its exact dimensions and sits under its size limit.",
      "example": "logo: acme-logo-224.png, 224×224, 38 KB · banner: acme-banner-1440.png, 1440×448, 164 KB",
      "pitfalls": [
        "The size ceilings are tight for photographic artwork. A flat logo compresses well under 50 KB; a photograph at the same dimensions will not."
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-275",
      "slug": "brd-275",
      "title": "Brands that buy, sell or share consumer data are not carried",
      "statement": "A brand whose business is buying, selling or sharing consumer information with third parties must not be registered for A2P messaging.",
      "rationale": "The channel rests on consent running from one consumer to one named sender, and a business whose product is the onward movement of consumer data breaks that link by design — whoever eventually messages the consumer is not who they agreed to hear from. It is refused at the brand rather than at the campaign because no campaign copy can repair a consent chain the business model is built to break.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.vertical + brand fields + website content",
      "severity": "BLOCKING",
      "detectability": [
        "AI_FORM",
        "CRAWL"
      ],
      "failureClass": "HARD_STOP",
      "authorities": [
        "Bandwidth",
        "AWS",
        "Bird",
        "Infobip",
        "Sinch",
        "Plivo",
        "Commio"
      ],
      "codes": [
        {
          "provider": "Bandwidth",
          "code": "7108",
          "remediable": false
        },
        {
          "provider": "Sinch",
          "code": "CR2012",
          "remediable": false
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "A lead-generation or data-broker business cannot be registered for A2P messaging. Where the business also has a first-party relationship — its own customers, its own service — register that entity and that programme separately, with consent collected directly and no onward sharing.",
      "notes": "The catalog is explicit that this is a brand-eligibility verdict rather than a site-content finding: the fix is a different channel, not a different page. Its campaign-content twin is CMP-AFFILIATE, which refuses affiliate marketing on the same reasoning one layer down.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-276",
      "slug": "brd-276",
      "title": "Gambling, betting and lottery brands are not carried",
      "statement": "A brand whose business is gambling, betting, casino, lottery or raffle must not be registered for A2P messaging.",
      "rationale": "Carriers exclude the whole category rather than policing it message by message, because gambling messaging reaches minors and problem gamblers through exactly the channel that is hardest to age-gate. The trap is that TCR publishes a GAMBLING vertical, so the registration form appears to invite the business it will then refuse.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.vertical + brand fields + website content",
      "severity": "BLOCKING",
      "detectability": [
        "AI_FORM",
        "CRAWL"
      ],
      "failureClass": "HARD_STOP",
      "authorities": [
        "AWS",
        "Bandwidth",
        "Bird",
        "Infobip",
        "Sinch"
      ],
      "codes": [
        {
          "provider": "Bandwidth",
          "code": "704",
          "remediable": false
        },
        {
          "provider": "Sinch",
          "code": "CR2013",
          "remediable": false
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "A gambling business cannot be registered for A2P messaging. Selecting the GAMBLING vertical does not open the category; it identifies the brand as ineligible. Use email or an app channel for these programmes.",
      "notes": "Note the vertical trap: TCR has a GAMBLING vertical and choosing it does not confer eligibility. The campaign-content twin is the SHAFT gambling prohibition in `message-shaft.ts`.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-277",
      "slug": "brd-277",
      "title": "High-risk financial services brands are not carried",
      "statement": "A brand whose business is high-risk financial services — payday and short-term lending, indirect loan marketing, stock alerts or crypto must not be registered for A2P messaging.",
      "rationale": "This category is where SMS fraud concentrates, so carriers exclude the business model rather than reading each campaign — the same message from a first-party lender and from a lead-selling loan site is indistinguishable in a text and very different in consequence. The cost of the blanket rule is that legitimate, licensed, first-party lenders get caught by it unless the carve-out is applied deliberately.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.vertical + brand fields + website content",
      "severity": "BLOCKING",
      "detectability": [
        "AI_FORM",
        "CRAWL"
      ],
      "failureClass": "HARD_STOP",
      "authorities": [
        "AWS",
        "Bandwidth",
        "Bird",
        "Infobip",
        "Sinch",
        "Plivo",
        "Vonage"
      ],
      "codes": [
        {
          "provider": "Bandwidth",
          "code": "709",
          "remediable": false
        },
        {
          "provider": "Sinch",
          "code": "CR2014",
          "remediable": false
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Where the business is a licensed first-party lender servicing its own loans, say so explicitly in the brand description and the campaign — the carve-out is real and it turns on first-party servicing. Where the business markets credit it does not originate, or promotes securities or crypto, it cannot be registered.",
      "notes": "The first-party carve-out is load-bearing and is the same one MSG-HIGH-RISK-FINANCIAL carries at the campaign layer; fixture 5 of the golden corpus exists to keep it from being dropped. Sinch permits 2FA-only traffic for stocks, investing and crypto businesses, which is why that carve-out is stated separately.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-278",
      "slug": "brd-278",
      "title": "Cannabis, CBD and related brands are not carried, whatever the traffic",
      "statement": "A brand whose business is cannabis, CBD, hemp derivatives, kratom or drug paraphernalia must not be registered for A2P messaging.",
      "rationale": "The prohibition attaches to the business rather than to the message, and it holds regardless of state legality — so a licensed dispensary sending nothing but appointment reminders or two-factor codes is still ineligible. That is the part legitimate operators do not believe until it happens: the traffic is harmless, the business is the disqualifier, and logistics companies serving the sector are caught by the same rule.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.vertical + brand fields + website content",
      "severity": "BLOCKING",
      "detectability": [
        "AI_FORM",
        "CRAWL",
        "EXTERNAL_DATA"
      ],
      "failureClass": "HARD_STOP",
      "authorities": [
        "AWS",
        "Bandwidth",
        "Bird",
        "Sinch",
        "Infobip",
        "Plivo"
      ],
      "codes": [
        {
          "provider": "Bandwidth",
          "code": "701",
          "remediable": false
        },
        {
          "provider": "Sinch",
          "code": "CR2015",
          "remediable": false
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "A cannabis-sector brand cannot be registered for A2P messaging in the US, including for two-factor or transactional traffic. Use email, an app, or a web channel for customer messaging.",
      "notes": "Absorbs MSG-191: the ban attaches to the business type, so it holds even for 2FA-only or purely transactional traffic, which is exactly what MSG-191 states at the message layer. Whether a business is licensed in the cannabis sector may need a state licence register the product does not hold, so a brand that reads as ambiguous should be confirmed by the user before submission rather than after.",
      "catalogIds": [
        "MSG-191"
      ],
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Does this business sell, distribute, or serve the cannabis, CBD, hemp, kratom or paraphernalia sector in any part of its trade?",
        "howToCheck": [
          "Ask what the business actually sells, not what these messages say. The prohibition attaches to the business and holds regardless of state licensing.",
          "Include logistics, payments and services to the sector — they are caught by the same rule.",
          "Where the answer is ambiguous, settle it before submitting rather than after."
        ],
        "failureLooksLike": "A licensed dispensary sending nothing but appointment reminders or two-factor codes is still ineligible. The traffic is harmless and the business is the disqualifier."
      }
    },
    {
      "id": "BRD-279",
      "slug": "brd-279",
      "title": "Third-party job boards are not carried",
      "statement": "A brand whose business is a third-party job board or staffing aggregator must not be registered for A2P messaging.",
      "rationale": "Job messaging is permitted from the employer that is actually hiring and refused from intermediaries, because recruitment texts from a company the recipient never applied to are the classic shape of an employment scam. Genuine job boards are caught by a rule aimed at the fraudulent ones, and the distinction the carriers draw is first-party hiring rather than legitimacy.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.vertical + brand fields + website content",
      "severity": "BLOCKING",
      "detectability": [
        "AI_FORM",
        "CRAWL"
      ],
      "failureClass": "HARD_STOP",
      "authorities": [
        "AWS",
        "Infobip",
        "Sinch"
      ],
      "codes": [
        {
          "provider": "Bandwidth",
          "code": "7001",
          "remediable": false
        },
        {
          "provider": "Sinch",
          "code": "CR2006",
          "remediable": false
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Job messaging must come from the hiring brand itself. Where you operate a board, the employer registers its own brand and messages its own candidates; where you place workers, message the workers you employ about their own engagements.",
      "notes": "Absorbs WEB-132, which states the same brand-level rejection decided from the site business model rather than from the form.",
      "catalogIds": [
        "WEB-132"
      ],
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-281",
      "slug": "brd-281",
      "title": "Sweepstakes brands are not carried",
      "statement": "A brand whose business is sweepstakes must not be registered for A2P messaging.",
      "rationale": "Sweepstakes messaging carries both a high complaint rate and real regulatory complexity — the rules differ by state and the prize claim is a natural phishing vector — so the category is excluded at the brand. TCR publishing a SWEEPSTAKE use case makes this genuinely confusing: the use case exists and is gated separately, and selecting it does not make the brand eligible.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.vertical + brand fields + website content",
      "severity": "BLOCKING",
      "detectability": [
        "CRAWL"
      ],
      "failureClass": "HARD_STOP",
      "authorities": [
        "AWS",
        "Bandwidth"
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "A sweepstakes business cannot be registered. Where an ordinary business runs an occasional promotion, keep the brand and the campaign about the business rather than about the draw, and expect the draw itself to need the separately gated use case.",
      "notes": "Decided from the website, which is why this is CRAWL rather than a form judgement — a sweepstakes operator rarely describes itself that way in the brand fields. Note that `use_case=SWEEPSTAKE` exists at TCR and is gated on its own terms; holding it does not make an ineligible brand eligible.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-282",
      "slug": "brd-282",
      "title": "Debt collection, debt relief and credit repair brands are not carried",
      "statement": "A brand whose business is third-party debt collection, debt consolidation or relief, or credit repair must not be registered for A2P messaging.",
      "rationale": "These are refused even with documented first-party consent, which is unusual and worth stating plainly: the category is excluded because the consumers reached are in financial distress and the sector has a long history of deceptive practice, so the consent record does not rescue it. Operators who have carefully collected written agreements from enrolled clients are the ones most surprised.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.vertical + brand fields + website content",
      "severity": "BLOCKING",
      "detectability": [
        "AI_FORM"
      ],
      "failureClass": "HARD_STOP",
      "authorities": [
        "Bird",
        "Infobip",
        "Sinch"
      ],
      "codes": [
        {
          "provider": "Sinch",
          "code": "7010",
          "remediable": false
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Third-party debt and credit-repair businesses cannot be registered, and a signed client agreement does not change that. A business chasing its own invoices should say so explicitly in the brand description, because that is first-party collection and is a different thing.",
      "notes": "Refused \"even with first-party consent\" in the catalog, which is why the remediation says so rather than suggesting better consent records. The campaign-content twin is MSG-DEBT, which carries the same first-party carve-out.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-283",
      "slug": "brd-283",
      "title": "Get-rich-quick, work-from-home and MLM brands are not carried",
      "statement": "A brand whose business is get-rich-quick, work-from-home, multi-level marketing, mystery shopping or risky investment schemes must not be registered for A2P messaging.",
      "rationale": "These categories are defined by what they promise rather than by what they sell, and the promise — income with little work — is the same one used by outright fraud. Carriers cannot separate the two from a text message, so the category goes. Distributors in a legitimate direct-sales company are caught by this and generally do not know the category includes them.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.vertical + brand fields + website content",
      "severity": "BLOCKING",
      "detectability": [
        "AI_FORM"
      ],
      "failureClass": "HARD_STOP",
      "authorities": [
        "Vonage",
        "Sinch",
        "Bird"
      ],
      "codes": [
        {
          "provider": "Sinch",
          "code": "7002",
          "remediable": false
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "These business models cannot be registered for A2P messaging. Where a legitimate product business has been mistaken for one, remove income and earnings claims from the brand description and the site — but if the model itself is recruitment-driven, no rewording makes it eligible.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-284",
      "slug": "brd-284",
      "title": "Controlled substance, prescription drug and pyrotechnics brands are not carried",
      "statement": "A brand whose business is controlled substances, prescription drugs, or fireworks and pyrotechnics must not be registered for A2P messaging.",
      "rationale": "Prescription and controlled-substance messaging is excluded because unsolicited drug texts are a recognised harm and the channel cannot verify a prescription; fireworks are excluded on straightforward safety and legality grounds that vary by state. Licensed pharmacies are the case that surprises people, and the boundary is between messaging about a patient's own prescription and promoting the medicine itself.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "brand.vertical + brand fields + website content",
      "severity": "BLOCKING",
      "detectability": [
        "AI_FORM"
      ],
      "failureClass": "HARD_STOP",
      "authorities": [
        "Sinch",
        "Bird"
      ],
      "codes": [
        {
          "provider": "Sinch",
          "code": "7005",
          "remediable": false
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "A brand whose business is controlled substances, prescription medicines or pyrotechnics cannot be registered. A licensed pharmacy or provider messaging its own patients about their own care should describe the programme in exactly those terms, since that is what the carve-out turns on.",
      "phase": "approval",
      "automated": true
    },
    {
      "id": "BRD-285",
      "slug": "brd-285",
      "title": "The brand must not be on the provider's own blocklist",
      "statement": "The brand must not appear on the submitting provider's internal blocklist.",
      "rationale": "Providers keep their own lists of businesses they will not carry, built from their own enforcement history rather than from any published standard — so a brand can satisfy every carrier requirement and still be refused by one provider and accepted by another. The rejection cites the list rather than a reason, which makes it look arbitrary from the outside even when it is not.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the brand identity against the provider blocklist",
      "severity": "BLOCKING",
      "detectability": [
        "EXTERNAL_DATA"
      ],
      "failureClass": "TERMINAL_EXTERNAL",
      "authorities": [
        "Sinch"
      ],
      "codes": [
        {
          "provider": "Sinch",
          "code": "CR2003",
          "remediable": false
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Where a provider refuses a brand on its own blocklist, ask them what triggered it before resubmitting anywhere — a prior enforcement action against a related entity is the usual cause, and it will follow the same details to the next provider. Registering the same business under a different name is a fabricated registration (BRD-286), not a workaround.",
      "notes": "The list is internal to the provider and is not published. What the user has to do is ask: providers will usually say whether the trigger is the business, the EIN, or a person named on the record, and that answer decides whether another provider is worth trying at all.",
      "phase": "approval",
      "automated": false,
      "attestation": {
        "question": "If a provider has refused this brand on its own blocklist, have you asked them what triggered it before submitting anywhere else?",
        "howToCheck": [
          "Ask the provider directly. They will usually say whether the trigger is the business, the EIN, or a person named on the record.",
          "That answer decides whether another provider is worth trying at all — a prior enforcement action against a related entity follows the same details.",
          "Re-registering the same business under a different name is a fabricated registration, not a workaround."
        ],
        "failureLooksLike": "The rejection cites the list rather than a reason, so it looks arbitrary. The same details are submitted to a second provider and refused for the same invisible history."
      }
    },
    {
      "id": "BRD-286",
      "slug": "brd-286",
      "title": "Fabricated business details are a permanent disqualification",
      "statement": "The brand record must describe a real business; fabricated details or a known scam pattern must never be submitted.",
      "rationale": "This is the one brand finding with no remediation: a registration judged fabricated is not corrected, it is refused, and the account behind it is reviewed. The reason is that a fake brand is the entire mechanism of an SMS scam — the identity is what a consumer would use to check who texted them, so inventing it defeats the framework rather than bending it. It matters here because well-meaning placeholder data on a demo brand is indistinguishable from the real thing.",
      "layer": "BRAND",
      "layerSlug": "brand",
      "object": "the whole brand record",
      "severity": "BLOCKING",
      "detectability": [
        "AI_FORM",
        "EXTERNAL_DATA"
      ],
      "failureClass": "HARD_STOP",
      "authorities": [
        "Twilio"
      ],
      "codes": [
        {
          "provider": "Twilio",
          "code": "30959",
          "remediable": false
        },
        {
          "provider": "Twilio",
          "code": "30885",
          "remediable": false
        }
      ],
      "applicabilityText": "Applies to every 10DLC registration.",
      "universal": true,
      "remediation": "Do not submit this registration. Every field must describe a business that exists, at an address it occupies, with a website it controls. If you are testing, use a mock brand (BRD-204), which burns no fee and pollutes no duplicate-detection index.",
      "notes": "Absorbs WEB-144, which is the same prohibition detected from the other side — site details that do not match public records. Twilio treats it as ineligible for resubmission, which is why this is HARD_STOP rather than a retry. The user cannot fix a fabricated record by editing it; what they have to do is register the real business, and if they believe the finding is wrong, appeal with documentation rather than resubmitting.",
      "catalogIds": [
        "WEB-144"
      ],
      "phase": "approval",
      "automated": true,
      "attestation": {
        "question": "Does every field on this brand describe a business that actually exists, at an address it actually occupies, with a website it actually controls?",
        "howToCheck": [
          "Go through the record field by field and name the source of each value: the IRS letter, the lease, the DNS registrar.",
          "Any value that came from a template, a placeholder, or 'we will fix it later' must be replaced before submission, not after.",
          "Testing rather than registering? Use a mock brand — it burns no fee and pollutes no duplicate index."
        ],
        "failureLooksLike": "A demo brand with plausible filler details submitted for real. It is indistinguishable from a fraudulent registration, and the outcome is refusal without resubmission plus a review of the account behind it."
      }
    }
  ]
}
