Give your agent a real phone number and an email inbox — in minutes, not days.
Your agent needs to call a person to move an appointment. Hail connects to the telephone carrier and runs the voice pipeline — STT, TTS, turn detection. Your agent is the brain: point Hail at any OpenAI-compatible endpoint (bring your own LLM), or let Hail's fallback chain (OpenAI → Gemini → Anthropic) do the talking. SMS and email work the same way — one MCP endpoint, one API key, one invoice.
Self-hostable with docker compose up. Open source under AGPLv3.
git clone https://github.com/hail-hq/hail
cd hail
cp .env.example .env # add Twilio, LiveKit Cloud, Deepgram, Cartesia keys
# + one of OpenAI / Gemini / Anthropic
docker compose upThen get an API key:
- Hail Cloud (managed, at hail.so): run
hail login. The device flow writes a key to~/.hail/credentials.json. - Self-host: seed a key into your database — see operations.md, "Self-host: first-run setup" — then set
HAIL_API_KEYor pass--api-key.
Full setup guides: Twilio · LiveKit Cloud · AWS SES · Webhooks · MCP
CLI (GitHub Releases):
hail login # authenticate (device flow)
hail auth logout # remove local credentials
hail auth token # print bare API key for scripting
hail call +14155550100 --prompt "be brief" --recipient-consent
hail call list
hail call status <id> # one call's state
hail call tail <id> # follow events for one call
hail sms +15551234567 --body "Hello!" --recipient-consent
hail sms list
hail sms status <id>
hail sms suppressions list # opt-out list
hail sms sender-id get # custom sender ID
hail numbers acquire # dedicated phone number (voice + SMS)
hail numbers list
hail contacts list # org contact directory
hail email send --to a@b.com --subject hi --body "hello" --recipient-consent
hail email list
hail email get <id>
hail email tail <id> # follow events for one email
hail email raw <id> # RFC 5322 source
hail email attachment <id> <att-id> --output file.pdf
hail email domain register --kind hail_mail
hail email domain register --kind custom --domain acme.com # send + receive on your own domain
hail email domain list
printf '%s' "$YOUR_API_KEY" | hail providers set llm \
--provider openai-compatible \
--base-url https://api.your-agent.dev/v1 \
--model your-model \
--key - # standing BYO brain (also: tts, stt)
hail tail # cross-channel event stream
hail tail call:<id> # narrow by resource type
hail mcp endpoint # Streamable HTTP URL for the MCP server
hail completion zsh # source <(hail completion zsh)
hail versionPython (pip install hail-sdk):
import asyncio
from hail import Client
async def main():
async with Client() as client: # reads $HAIL_API_KEY
call = await client.calls.create(
to="+15551234567",
recipient_consent=True,
system_prompt="You are calling to confirm a reschedule.",
)
async for event in client.events.tail(id=f"call:{call.id}"):
print(event.kind, event.payload)
asyncio.run(main())HTTP (OpenAPI spec, API reference):
curl -X POST http://localhost:8080/calls \
-H "Authorization: Bearer $HAIL_API_KEY" \
-d '{"to":"+15551234567","recipient_consent":true,"system_prompt":"..."}'MCP (Claude.ai, Claude Code, ChatGPT, Cursor, …): add a remote MCP connector pointing at http://<your-host>:8081 (self-hosted). See setup/mcp.md.
Hail always runs the telephony and the voice pipeline. The brain is pluggable, at two levels:
- Per call — pass an
llmblock toPOST /calls; different brains for different calls. - Standing — save an endpoint once (
hail providers set llm …); every call your org places uses it.
Any OpenAI chat-completions-compatible endpoint works. A complete runnable example lives in docs/public/byo-llm.md. TTS and STT are pluggable the same way (hail providers set tts|stt …).
- Clear comms. Explicit OpenAPI contracts. No hidden behavior.
- Simple code. Boring is best. No abstraction before it has two uses.
- Brief docs. Each page fits on one screen. Setup takes 10 minutes from a fresh clone.
- Self-hostable.
docker compose upruns everything except LiveKit Cloud. - Pluggable brain. BYO LLM endpoint, or Hail's bundled fallback. The voice pipeline and transport are always Hail's.
- Agent-first docs. AI agents are first-class readers. Runnable examples first; links to canonical sources, not paraphrase.
A checked box is a released feature. Per-artifact changelogs (GitHub Releases for the CLI, PyPI notes for the SDK) record which version shipped it.
- Outbound
- Twilio
- Telnyx
- Inbound
- Twilio
- Outbound
- Twilio
- Inbound
- Twilio
- Outbound
- AWS SES
- Custom sender domains (own DNS, automatic DKIM + MAIL FROM)
- Inbound
- AWS SES
- Custom domains (receive on verified domains)
- Languages
- 39 call languages with automatic STT routing and per-language turn detection — see docs/languages.md
- STT
- Deepgram
- Speechmatics
- Whisper
- AssemblyAI
- TTS
- Cartesia
- ElevenLabs
- Deepgram Aura
- VAD
- Silero
- Turn detection
- LiveKit turn-detector
- LLM — system-prompt mode
- Fallback: OpenAI → Gemini → Anthropic, fast models
- LLM — BYO-endpoint mode
- OpenAI chat-completions-compatible (docs)
- Recording
- S3 upload
- Diarization
- API
- OpenAPI spec + hosted reference
- CLI
-
hailbinary via GitHub Releases
-
- MCP server
- Remote Streamable HTTP endpoint included with each Hail deployment
PyPI stdio package— deliberately not shipped; see setup/mcp.md
- Python SDK
-
hail-sdkon PyPI, imports ashail
-
- Docker Compose scaffold
- Self-hosted LiveKit SFU
- docker compose integration
The path of an outbound call:
AI agent ──► Hail API ──dispatch──► Voicebot ──► LiveKit Cloud ──SIP──► Twilio ──► 📞
Full diagram and service breakdown: docs/public/architecture.md. All docs are published at hail.so/docs and live as plain markdown in docs/public/.
See docs/public/contributing.md. Short version: fork, branch, conventional commits, pull request. Provider adapters go in core/hailhq/core/providers/; new env vars update .env.example in the same commit.
Code: AGPL-3.0-or-later — run a modified Hail as a service, release your source.
Pricing dataset (costs/): CC-BY-4.0 — use the JSON with attribution.