# MSG-296 — Platform sample specifications must be met where an ISV imposes one

> Where the campaign is registered through an ISV that publishes its own sample specification, the samples must satisfy it — for HubSpot, exactly two samples, each carrying the business name, opt-out instructions including STOP, a privacy-policy link, and bracketed personalisation.

- **Rule ID:** MSG-296
- **Layer:** Message content (`MESSAGE_CONTENT`)
- **Checks:** `campaign.sample[]`
- **Severity:** BLOCKING — Breaking this rule gets the submission rejected outright.
- **When it bites:** Gates approval — get this wrong and registration is refused
- **How it is detected:** Deterministic (settled in code from the submitted values)
- **Fix type:** Fix the field — a better value in the form clears it
- **Required by:** HubSpot
- **Applies:** Applies when the submission target is HUBSPOT.
- **Canonical URL:** https://ekas.io/rules/10dlc/message-content/msg-296/

## Why this rule exists

An ISV sits between the business and TCR and applies its own acceptance rules first, so a submission that would clear every carrier requirement is still rejected at the platform without ever reaching a carrier. HubSpot publishes the strictest sample specification found anywhere — a superset of what any carrier asks — and businesses meet the carrier bar, submit, and are refused by their own tooling with no reference to a carrier rule they can look up. It is worth stating separately because the fix is cheap and the confusion is expensive: nothing is wrong with the campaign, only with the shape of it for one route.

## How to fix it

Submit exactly two samples and put all four elements in each: the business name at the front, "Reply STOP to opt out", a link to your public privacy policy, and at least one [bracketed] personalisation token. Done when both samples carry all four — HubSpot checks each sample independently rather than the set as a whole.

## Example of a compliant value

```text
sample1: "Acme Coffee: hi [first name], 20% off all espresso blends this weekend. Privacy: https://acmecoffee.com/privacy Reply STOP to opt out."
sample2: "Acme Coffee: hi [first name], order [order number] is ready for pickup. Privacy: https://acmecoffee.com/privacy Reply STOP to opt out."
```

## Common mistakes

- The privacy policy behind the link has to carry the mobile-information non-sharing statement and the rates disclosure — a link to a generic generated policy satisfies this rule and is then rejected on the policy itself.

## Notes

Provider-tagged rather than applied as a superset, and that is the whole point of the tag here: this is one vendor's contract, not a carrier requirement, so imposing it on everyone would fail compliant registrations for not doing something no carrier asks. The check returns UNCLEAR while the submission target is unknown, because "we do not know which platform you are using" is the honest answer and returning a vacuous PASS would hide the requirement from the users who owe it. Source: aws-and-resellers.md section A, HUBSPOT-REG.
