Carrier Registration
Register a US number for SMS with 10DLC or toll-free verification
Carrier Registration
US carriers require a number to be registered before it can send SMS. Zernio runs that registration through the API. There are two paths, both handled by startSmsRegistration (POST /v1/sms/registrations):
- 10DLC - for local (10-digit long code) numbers. Standard (company) or sole-proprietor. Needs a
brandand acampaign. - Toll-free verification - for toll-free numbers. Needs the
tollFreedetails.
Approval is asynchronous. Poll getSmsRegistration (GET /v1/sms/registrations/{id}) to know when a number goes live. Do not assume delivery until the status is approved. Registration is a US requirement only: a number in any other country can send as soon as SMS is enabled on it.
What registration costs
Registration bills two fees to your usage invoice: a $9 one-time brand fee, and a recurring monthly campaign fee of $20/month for standard 10DLC and toll-free, or $4/month for sole proprietors. The fees are shown before you submit, and per-destination message rates are in the SMS price list. Reusing an approval on additional numbers incurs no new fees.
Enable SMS on the number first
Before registering, enable SMS on the number (POST /v1/phone-numbers/{id}/sms). Its response tells you whether a reusable, approved registration already exists on your account (see Reuse).
curl -X POST "https://zernio.com/api/v1/phone-numbers/PHONE_NUMBER_ID/sms" \
-H "Authorization: Bearer YOUR_API_KEY"Start a 10DLC registration
const { data } = await zernio.sms.startSmsRegistration({
body: {
phoneNumbers: ['+14155551234'],
registrationType: 'standard_10dlc',
brand: { /* legal business details */ },
campaign: { /* use case, sample messages */ },
}
});
console.log(data.registrationId, data.status);curl -X POST "https://zernio.com/api/v1/sms/registrations" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phoneNumbers": ["+14155551234"],
"registrationType": "standard_10dlc",
"brand": {},
"campaign": {}
}'Carriers reject sparse filings, so several brand and campaign fields are hard requirements: the brand needs a website (sole props may use a social profile URL instead), a full street address (street, city, state, postalCode), and, for company / non-profit / government brands, a business phone. The campaign needs a use case, a description, opt-in/opt-out/help keywords and messages, and two sample messages (sample1 and sample2, 20+ characters each). Missing any of these returns a 400 naming the field.
Sole-proprietor registrations add an OTP step. A code is texted to the brand's mobile number; submit it with verifySmsRegistrationOtp (POST /v1/sms/registrations/{id}/verify-otp) to continue. Standard company registrations skip this.
Reuse an approval (skip the fee)
Carriers charge a brand fee per registration. If you already have an approved 10DLC campaign, do not register again: attach the new number to it with reuseSmsRegistrationForNumber (POST /v1/phone-numbers/{id}/sms/reuse-registration). The number inherits the campaign's approval, with no new brand or campaign and no extra carrier fee.
curl -X POST "https://zernio.com/api/v1/phone-numbers/PHONE_NUMBER_ID/sms/reuse-registration" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"registrationId": "EXISTING_REGISTRATION_ID"}'Hand the form off (white-label)
If your customer holds the legal business details, shareSmsRegistration (POST /v1/sms/registrations/share) creates a single-use link (valid 7 days) that lets them fill in the registration form with no Zernio login. The registration is created under your account once they submit.
Track and appeal
List registrations with listSmsRegistrations (GET /v1/sms/registrations) and check one with getSmsRegistration (GET /v1/sms/registrations/{id}). A registration is always in one of three states:
status | Meaning | What to do |
|---|---|---|
pending | Submitted and under carrier review. On a sole-prop registration, awaitingOtp: true means it is paused on the OTP step and won't progress until you verify the code. | Poll, or wait. Messages don't deliver yet. |
approved | The registration is live; every number attached to it can send. | Start sending, or attach more numbers. |
rejected | The carrier declined it; declineReason says why. | Fix and appeal (below). |
The response also exposes the raw carrier-registry fields (brandStatus, campaignStatus, trustScore) — useful when referencing the filing in carrier support threads, but status is the field to branch on. Statuses are not one-way: an approved registration can drop back to pending if the carrier registry suspends the campaign, so treat status as the current state rather than a completed milestone.
A rejected campaign is appealed with appealSmsRegistration (POST /v1/sms/registrations/{id}/appeal): pass an appealReason that addresses the decline reason directly, and fix the flagged content in the same call (messageFlow, sample1, sample2 — the currently filed content is returned as campaignContent on a rejected registration). On success the registration returns to pending for re-review. A brand-level rejection cannot be appealed: correct the brand details and re-verify instead.
Next steps
- Send SMS and MMS once the number is approved