hail CLI v0.10.0
0.10.0 — 2026-07-09
SMS outbound milestone. Hail can now send SMS via Twilio, gated by the same
consent, suppression, and velocity-cap infrastructure as calls and email.
Component versions cut alongside this umbrella release:
sdk-v0.7.0 (PyPI: hail-sdk==0.7.0), cli-v0.10.0 (Homebrew + GitHub Releases).
SMS outbound
SmsProviderinterface incore/hailhq/core/providers/sms/withTwilioSmsProvidershipping.Smsmodel (smstable) andSmsEventmodel (sms_eventstable, feeding the unified event stream below).- Requires a dedicated, SMS-capable phone number on the organization — unlike calls, SMS does not fall back to a shared pool number, since a pool number cannot provide unambiguous number-to-org routing for a channel with no forced voice-menu context.
- A carrier-level rejection (e.g. an unregistered or filtered number) is recorded as a failed, unbilled send with the carrier's
error_code— not a false "sent" status, and not charged. Suppression.channelCHECK widened to includesms; newcheck_sms_allowedgate mirrors the existing call/email checks. SMS velocity caps count attempted sends rather than billed sends, so a burst of carrier-rejected probing still trips the cap.- Audit-log shape change (calls): generalizing the phone-channel compliance gate to cover SMS renamed the call
audit_log.payload.checkskeysinternal_dnc_checked/internal_dnc_hittosuppression_checked/suppression_hit(voice and SMS now share one destination scrub). Update any external queries or dashboards that match the old key names; existing rows are not backfilled. - SMS content is now covered by the existing DSAR export/delete and account-closure retention flows, on the same schedule as call transcripts and email content.
API
POST /sms,GET /sms/{id},GET /sms.- Unified
/eventsstream (GET /events) extended to a three-way union across calls, email, and SMS;EventResponse.sourcenow includessms. - Fixed: a same-idempotency-key retry of a request that failed pre-send validation (e.g. a malformed body, or a 403 from the consent/compliance/balance gates) previously replayed as "still processing" until the idempotency key expired, instead of replaying the original failure. Now also covers the per-call BYO
llm.base_urlsafety rejection; the shared-pool-exhausted503on/callsreleases the key instead, so a same-key retry can go through once capacity frees. Affects/calls,/emails, and/sms. - Fixed: an outbound voice call with no explicit
fromcould select an SMS-only number;/callsnow resolves a from-number carrying thevoicecapability (mirroring/sms'ssmsrequirement) and falls back to the shared voice pool otherwise.
CLI (cli-v0.10.0)
- New
hail sms send / status / listsubcommand. hail tail(unified event stream) surfacessms:resource IDs alongsidecall:andemail:.
SDK (sdk-v0.7.0)
client.sms.create / get / listresource added.- Resource-ID parsing (
client.events.get) widened to acceptsms:alongsidecall:andemail:.
MCP
send_sms,get_sms,list_smstools added (eleven → fourteen tools total).
Deferred to next milestone
- Inbound SMS: webhook receipt, STOP/HELP/START opt-out keyword processing.
- Self-serve dedicated-number provisioning — today, assigning a number to an organization is a manual database operation; see
docs/operations.md. - Custom per-org Sender ID (international, outbound-only corridors).
- Console UI for SMS activity, numbers, and suppression management.