Short-code preflight: checks and remediation
A short-code application goes through per-carrier vetting that runs for weeks, and carriers reject roughly a third of first-round program briefs on deterministic grounds — restricted content, ambiguous calls to action, missing opt-out or disclosure wording. The preflight engine scores your program brief against that known rejection-pattern catalog before it enters the carrier queue, returning a score, a verdict, and per-field findings with the exact offending fragment and a concrete rewrite suggestion. This page is the reference for that engine: the posture it runs under, the endpoint surface, every rule it checks, the remediation for every failure code, and the preflight → resubmission → carrier-verified lifecycle. For the end-to-end submission walkthrough (opening the application and tracking carrier vetting), see Apply for an SMS short code.Role and posture
The preflight follows the same posture as every Orbit compliance control except the federal TCPA dialing window: tenant-controlled, default-open, advisory-only unless you enforce.- Advisory, never a gate. The endpoint only reads your brief and
reports findings. It cannot block a submission, and it never touches
sending — a
blockverdict is information for your submission decision, not an enforced stop. If your compliance policy requires a passing preflight before submission, enforce that in your own workflow. - Default-open. No org toggle gates the endpoint; any authenticated caller with a read-capable role can lint a brief.
- A clean pass is not carrier approval.
passmeans “no known rejection pattern matched.” The application still goes through the normal per-carrier vetting, which includes human review.
Endpoint surface
Two endpoints run the same engine (shortcode-preflight/v1), and all
routes below are rooted at https://api.orbit.devotel.io/api/v1:
Field-by-field verification matrix
These are the request fields, their shape constraints (a violated constraint returns422 VALIDATION_ERROR with per-field details), and
what the engine checks:
Response shape
score— 0–100; 100 means no known pattern matched.verdict—pass,warn, orblock.findings[]— one entry per rule hit.fieldis the dot-path of the offending field (e.g.programBrief.sampleMessages[2]);matchquotes the exact fragment when one exists;suggestionis the rewrite that resolves the finding.engine— the rule-engine version, stamped on every response so you can correlate score changes when the catalog evolves.
Failure catalogue
Each finding carries a stableruleId. The table covers every code the
v1 engine emits, with the remediation for each.
The four Call-to-Action rules (
R-SC-CTA-*) only evaluate once the
opt-in description clears the substance gate — a flow too thin to vet
fails R-SC-OPTIN-LEN first, and per-disclosure findings would be
noise until the flow is actually described.
Scoring. Each error finding deducts 25 points, each warn 8,
each info 2. The verdict is block when any error-severity finding
is present, warn when the score lands below 75, otherwise pass.
Lifecycle: preflight → resubmission → carrier-verified
The lint sits inside the application lifecycle as an advisory checkpoint you can run at every draft stage:- Lint before the application exists. Run the ad-hoc
POST /numbers/short-codes/preflightwhile drafting the brief — before an application is even opened. - Lint the stored draft. Once the application exists (
draftstatus), fix findings withPATCH /numbers/short-codes/:id/brief, then re-runPOST /numbers/short-codes/:id/preflight. Repeat until the verdict ispass. Both lint endpoints are idempotent reads. - Submit. With a passing brief,
POST /numbers/short-codes/:id/submitlocks the brief and starts per-carrier vetting. - Carrier-verified. Carriers approve the program and the lease is
provisioned — the verdict that actually authorizes sending. The
preflight
passwas the deterministic first pass; provisioning is the authoritative one.
Worked carrier-complaint cycle
The loop the preflight exists to shorten: a rejection comes back from vetting, and you need to turn a corrected brief around without re-entering the queue blind.- Read the reason. A rejected application carries the aggregator
or carrier
rejectionReason— fetch it withGET /numbers/short-codes/:id: “Program rejected: published CTA missing opt-out wording.” - Open a new application. Rejection is terminal (the brief is
locked), so open a fresh draft with the corrected
programBrief. For a CTA-wording rejection like the above, that means the opt-in description now carries frequency, rates, STOP, and HELP disclosures. - Re-run the preflight against your original failure class. Lint
the new draft with
POST /numbers/short-codes/:id/preflightand confirm the finding class is gone. For the CTA example, expect noR-SC-CTA-*findings. - Resubmit when clean.
POST /numbers/short-codes/:id/submitre-enters the queue with a brief that has no known rejection pattern left to match.
See also:
- Apply for an SMS short code — the carrier-submission walkthrough: lease type, lifecycle statuses, vetting timeline, and audit events.
- Opt-Out & Suppression Lists — how the STOP wording your brief promises is enforced on inbound replies.