New features, improvements, and fixes to Dial

July 29, 2026

Added

Register a US number for 10DLC

US carriers block outbound SMS and MMS sent from an unregistered 10-digit number to a US phone number. You can now register a number for 10DLC through the API and lift that block:

  • POST /api/v1/numbers/{id}/10dlc submits the registration — application/json carrying kind (sole_proprietor or business), a brand (who is registering) and a campaign (what you send, and how people opted in). It costs $25.00 one-time per number, drawn from your credit balance; resubmitting after a rejection is free.
  • GET /api/v1/numbers/{id}/10dlc returns the brand, the campaign, and where the registration stands.
  • Phone numbers carry a new tenDlc object reporting where the registration stands: not_registered, in_review, with_carrier, approved, or rejected (with a reason saying exactly what to change). It’s null when 10DLC doesn’t apply — a non-US number, a number with the imessage capability, or an account that isn’t pay-as-you-go and has no registration yet.

Dial emails you on approval and on rejection. Inbound texts, voice calls in either direction, and messaging to numbers outside the US are unaffected by the carrier block, registered or not.

See Register a US number for 10DLC for the full field lists.

Fixed

A number bought on a subscription is covered immediately

Provisioning a number on a flat-rate subscription now attaches it to the subscription as part of the same operation, so POST /api/v1/numbers returns a number you can send and call from right away.

Previously coverage was attached only when the prorated subscription invoice was paid. If that purchase raised no invoice — which happens when you hold no numbers, because the subscription already bills a minimum of one — the number stayed uncovered, and every message and call from it failed with subscription_coverage. Releasing your only number and provisioning a replacement hit exactly that case.

Changed

10DLC submissions are now brand + campaign

POST /api/v1/numbers/{id}/10dlc changed shape a few hours after it first shipped. It was briefly multipart/form-data with a flat data part and an optInImage file; it now takes application/json with a brand object and a campaign object, matching what the carrier registry actually registers.

What this means if you submitted in that window:

  • The screenshot is gone. The carrier registry has nowhere to put it, so the field was removed rather than left implying carriers require it. optInImageUrl is no longer returned, and your opt-in flow is described in the campaign’s messageFlow.
  • Field names and values follow the registry. useCaseDescription is now the campaign’s description; sample1/sample2 are the campaign’s samples array; ein is registrationNumber; and select values are the registry’s own codes (Limited Liability Corporation, TELECOMMUNICATIONS, CUSTOMER_CARE). numberCount, social, regions and companyType are gone — the registry never used them.
  • The registered address is no longer US-only. A business may be registered from any country the registry accepts — country is an ISO 3166-1 alpha-2 code, and state is the two-letter code in the US and Canada or the region name elsewhere. Sole proprietor registration remains US/Canada-only.
  • phone must be E.164. Include the country code; a number without one can’t be read reliably for a brand registered outside the US.
  • businessRegionsOfOperation and companyType are collected (plus stockExchange and stockTicker for a public company), because the carrier registry’s own policies name them.
  • Sole proprietors now supply a brandName and two samples. The registry requires both for every campaign, and the earlier form didn’t ask.
  • A registration submitted under the old shape must be resubmitted. Anything still in review has been rejected with a reason saying so; resubmitting is free, as always.

A subscription always bills at least one number

The subscription quantity now tracks your number count with a floor of one, and releasing a number keeps the two in step:

  • Releasing a number lowers the quantity by one (prorated by Stripe), but never below one. Releasing your last number leaves the subscription active at the single-number rate instead of cancelling it — cancel with POST /api/v1/billing/subscription/cancel to stop paying.
  • While you hold no numbers, the next number you provision is free: the quantity is already at the floor, so no prorated charge is raised. Holding zero numbers and holding one cost the same, and swapping a number costs nothing.
  • quantity on subscription in GET /api/v1/billing counts the numbers the subscription covers, so it reads 0 while you hold none. The amount billed is max(quantity, 1) × the unit price.

Previously a release left the quantity untouched, so the subscription kept billing for a number that no longer existed.

iMessage numbers are pay-as-you-go only and never part of a subscription, so none of this applies to them.