welldun. offhook

Open source·Apache-2.0

AI phone calls you can run yourself.

Offhook places and answers real phone calls with an AI agent. Bring your own provider keys, run it on your own servers, and get a transcript and a full event log for every call.

Python · Postgres · built on Pipecat

8f2c4d1e-… Example completed
To
+1 415 555 0123
Agent
Alex · Acme Clinic
Context
Priya · Tuesday at 3 PM
  1. queued00:00.0
  2. dialing00:00.4
  3. in progress00:06.1
  4. completed01:48.3

AgentHi, this is Alex from Acme Clinic. Am I speaking with Priya?

CallerYes, that's me.

AgentI'm calling to confirm your appointment with Dr. Rao on Tuesday at 3 PM. Does that still work?

CallerIt does, thanks.

Outcome{"confirmed": true}

How it works

Three requests to a real phone call.

  1. 01

    Connect your keys

    Register your Deepgram, Cartesia, LLM and carrier keys as connections. Each one is encrypted with a key that belongs to your account, and decrypted only while a call is running.

  2. 02

    Define an agent

    Give it instructions, an opening line, a voice and a model, and pick the connections it runs on. Reuse the same agent across every call.

  3. 03

    Place the call

    Send a phone number and any facts the agent should know. A worker dials, the agent talks, and you get a webhook at every step until the call ends.

curl -X POST localhost:8000/v1/connections \
  -H "Authorization: Bearer $OFFHOOK_KEY" \
  -H "content-type: application/json" \
  -d '{
    "name": "my-groq",
    "provider_kind": "llm",
    "provider_name": "groq",
    "secrets": {"api_key": "gsk_..."}
  }'

What's included

The plumbing a production call needs.

Calls
Outbound and inbound. An async dial queue, idempotency keys so a retried request never rings anyone twice, and clear states from queued to completed.
Agents
Instructions, an opening line, a voice and a model for each agent. Built-in tools to record results and end the call, plus your own HTTP tools for live data mid-call.
Providers
Deepgram for speech-to-text. Cartesia or OpenAI for text-to-speech. Groq, Gemini, OpenAI or OpenRouter for the model. Plivo or Twilio for the phone line.
Call records
An event timeline, transcript, recording, structured outcome and stable error code for every call. Signed webhooks with retries for every change.
Security
Provider keys stored with per-tenant envelope encryption, using a master key from the environment or AWS KMS. Hashed API keys, an SSRF guard and log redaction.
Limits
Per-tenant rate limits, concurrent-call caps and monthly quotas, with usage metered in billable seconds.

Quickstart

Talk to an agent in your browser first.

You don't need a phone number to start. The playground runs the same pipeline over your microphone. You need Python 3.13, Docker, and free-tier keys from Deepgram, Cartesia and Groq.

Terminal
git clone https://github.com/welldunai/offhook.git
cd offhook
uv venv && source .venv/bin/activate
uv pip install -e .

# add your Deepgram, Cartesia and Groq keys
cp .env.example .env

# Postgres, migrations, a dev tenant and a demo agent
docker compose up -d
alembic upgrade head
python -m app.admin seed-dev \
  --voice-id 05a69c2d-457a-4802-8f91-628cb158b522

# then open http://localhost:8000 and start talking
python run.py