1. Run callhook

One line installs the single binary — backend, campaigns and the war-room web app all embedded:

$ curl -fsSL https://callhook.github.io/install.sh | bash
$ ./callhook/callhook_linux_amd64/callhook

# or from source
$ git clone https://github.com/iSundram/callhook && cd callhook/backend
$ go run ./cmd/callhook

CALLHOOK_API_KEY not set — running in DRY-RUN mode (no real calls placed)
callhook dev listening on :8080 (dashboard: http://localhost:8080/)
supported events: invoice.due, account.warning, promo.offer
retries: redial after 2h, up to 2 retries | windows: true

No CALLHOOK_API_KEY? callhook runs in dry-run mode: the whole pipeline executes — events, prefetch, retry policy, outcome engine, dashboard — but calls are fabricated locally. Perfect for development, zero cost.

2. The war room

Open http://localhost:8080/ — the war room, callhook's web app (embedded in the binary). Connect, then fire demo events, browse transcripts and audit trails in Sessions, or launch a goal-driven campaign from Campaigns and watch the audience grid fill live.

3. Fire a real event

$ curl -X POST localhost:8080/api/events -H 'Content-Type: application/json' -d '{
    "id":          "evt_001",
    "type":        "invoice.due",
    "customer_id": "cus_1002",
    "callback_url": "https://your-app.example.com/hooks/callhook"
  }'

# → {"status":"call_placed","session_id":"evt_001","call_id":"call_...","phone":"+14155550002"}

The response returns immediately. When the call finishes, callhook POSTs the structured outcome to your callback_url:

{
  "event_id":    "evt_001",
  "call_status": "completed",
  "outcome":     { "outcome": "payment_promised", "promise_date": "2026-09-12" },
  "actions":     ["write.mark_promise(inv_5002 → 2026-09-12)", "audit.record_contact"],
  "confidence":  { "score": 0.93, "label": "high" },
  "transcript":  [ ... ]
}

4. Or use the CLI

$ go run ./cmd/callhookctl fire invoice.due cus_1002 --not-before 2026-09-07T14:00:00Z
$ go run ./cmd/callhookctl batch events.json      # fire many at once
$ go run ./cmd/callhookctl sessions --watch
$ go run ./cmd/callhookctl metrics

5. Going live

Dry-run proves the pipeline. For real phone calls, all you change is the environment — see Production.