* feat(webhooks): durable retrying delivery for final webhooks
Final webhook nodes were fired inline with a single best-effort httpx POST
(run_integrations._execute_webhook_node). On a transient error the failure was
swallowed at three levels, so ARQ never retried and the final call report was
permanently lost -- leaving downstream receivers stuck (e.g. a CRM showing a
call as still "in conversation").
Replace the one-shot POST with a durable, idempotent delivery pipeline modelled
on the campaign retry pattern (persisted row + scheduled_for + bounded attempts):
- New webhook_deliveries table (WebhookDeliveryModel) is the source of truth.
Payload is rendered once and frozen so retries are deterministic; secrets are
not stored -- the credential is referenced by uuid and re-resolved at send time.
- run_integrations now persists a delivery row and enqueues deliver_webhook with
a deterministic ARQ job id instead of sending inline.
- deliver_webhook (new ARQ task) sends the request and:
* 2xx -> succeeded
* transient -> retry with capped exponential backoff (RequestError /
5xx / 408 / 425 / 429), up to max_attempts then dead_letter
* permanent 4xx -> dead_letter immediately (no pointless looping)
It is idempotent: a non-pending delivery is a no-op, so a duplicate enqueue or
sweeper re-injection can't double-send.
- sweep_webhook_deliveries cron (every 5 min) re-enqueues overdue pending
deliveries so nothing is lost to a worker restart / Redis flush.
- Stable X-Dograh-Delivery-Id / Workflow-Run-Id / Attempt headers let receivers
dedupe retried deliveries.
- enqueue_job now forwards ARQ job options (_job_id, _defer_by); failures log
repr(e) so empty-message errors like ConnectTimeout are diagnosable.
Config via DEFAULT_WEBHOOK_DELIVERY_CONFIG (env-overridable): max_attempts=5,
base_delay=30s, max_delay=600s, timeout=30s.
Tests cover payload rendering, persist+enqueue, success, transient retry,
retryable 5xx, permanent 4xx dead-letter, attempt exhaustion, and idempotency.
Migration verified to apply/rollback against Postgres; table/enum/indexes confirmed.
* fix(webhooks): atomic claim, safe success-recording, sweep paging, migration cleanup
Address review feedback on the webhook delivery pipeline:
- deliver_webhook now atomically claims a delivery (conditional UPDATE that
leases scheduled_for) before sending, so concurrent ARQ executions can't
double-send (the prior status=='pending' read was non-atomic).
- Recording success is moved out of the dead-letter try-block: if the receiver
accepted the payload (2xx) but the success DB-write fails, the row is left
pending for the sweeper to reconcile instead of being dead-lettered.
- The sweep keyset-paginates by id so a backlog over the page size is fully
drained, and logs the true re-enqueued total.
- Migration downgrade drops the enum via op.execute(DROP TYPE IF EXISTS ...)
instead of the deprecated op.get_bind().
* fix(webhooks): idempotent delivery creation and drop secret custom headers
Address the remaining review feedback:
- Add a (workflow_run_id, webhook_node_id) unique constraint and make
create_webhook_delivery a get-or-create returning (delivery, created). A
retried run_integrations now reuses the existing row instead of creating and
sending a duplicate final webhook; only a freshly-created row is enqueued.
- Stop persisting secret-looking custom headers (Authorization, X-API-Key,
Cookie, ...) in plaintext on the delivery row: they are dropped with a warning
pointing at the credential store (which is re-resolved securely at send time).
Non-secret custom headers are unaffected.
* fix(webhooks): harden idempotency key, secret-header match, sweep reclaim id
Address follow-up review feedback:
- webhook_node_id is now NOT NULL so a NULL can't slip past the
(workflow_run_id, webhook_node_id) unique constraint and create duplicates.
- Secret-header filtering matches normalized markers (auth/token/secret/cookie/
api-key/...) instead of an exact name list, catching variants like
X-Custom-Auth-Token while leaving benign headers (e.g. X-Idempotency-Key).
- The sweeper re-enqueues with a reclaim-specific job id (the lease timestamp)
so reconciling a delivered-but-unrecorded row isn't deduped against the
original attempt's already-completed ARQ job. The atomic claim still ensures
at most one send.
* fix(webhooks): scope delivery rows to workflow org
---------
Co-authored-by: Abhishek Kumar <abhishek@a6k.me>
|
||
|---|---|---|
| .agents/skills | ||
| .devcontainer | ||
| .github | ||
| .vscode | ||
| api | ||
| config/coturn | ||
| deploy | ||
| docs | ||
| evals | ||
| examples | ||
| nginx | ||
| pipecat@63f0bc437e | ||
| scripts | ||
| sdk | ||
| ui | ||
| .dockerignore | ||
| .gitignore | ||
| .gitmodules | ||
| .nvmrc | ||
| .python-version | ||
| .release-please-manifest.json | ||
| AGENTS.md | ||
| CHANGELOG.md | ||
| CLAUDE.md | ||
| CONTRIBUTING.md | ||
| docker-compose-local.yaml | ||
| docker-compose.yaml | ||
| LICENSE | ||
| PRIVATE_DEPLOYMENT_PLAN.md | ||
| README.ja-JP.md | ||
| README.md | ||
| README.zh-CN.md | ||
| release-please-config.json | ||
| remote_up.sh | ||
| SECURITY.md | ||
Dograh AI
The open-source, self-hostable alternative to Vapi & Retell — build production voice agents with a drag-and-drop workflow builder. From zero to a working bot in under 2 minutes.
📖 Docs · 📜 BSD 2-Clause · 🌐 中文 · 🌐 日本語
- 100% open source, self-hostable — no vendor lock-in, unlike Vapi or Retell
- Full control & transparency — every line of code is open, with flexible LLM / TTS / STT integration
- Maintained by YC alumni and exit founders, committed to keeping voice AI open
🎥 Featured
⚖️ Dograh vs Vapi vs Retell
An honest comparison on the axes that matter most to teams evaluating voice AI platforms.
| Dograh | Vapi | Retell | |
|---|---|---|---|
| License | BSD 2-Clause (open source) | Proprietary | Proprietary |
| Self-hostable | ✅ Yes — one Docker command | ❌ SaaS only | ❌ SaaS only |
| Pricing | Free (self-host) · usage-based (cloud) | Per-minute SaaS | Per-minute SaaS |
| Bring your own LLM / STT / TTS | ✅ Any provider, or use Dograh's stack | Configurable within their integrations | Configurable within their integrations |
| Source-level customization | ✅ Every line is yours to modify | ❌ Closed source | ❌ Closed source |
| Data residency | Your infra, your rules | Their cloud | Their cloud |
| Vendor lock-in | None | Full | Full |
🚀 Get Started
Download and setup Dograh on your Local Machine
Note
We collect anonymous usage data to improve the product. You can opt out by setting
ENABLE_TELEMETRY=falsebefore running the startup script.
Note
If you wish to run the platform on a remote server instead, checkout our Documentation
curl -o docker-compose.yaml https://raw.githubusercontent.com/dograh-hq/dograh/main/docker-compose.yaml && curl -o start_docker.sh https://raw.githubusercontent.com/dograh-hq/dograh/main/scripts/start_docker.sh && chmod +x start_docker.sh && ./start_docker.sh
⚡ Prefer an AI agent to set it up for you? If you use Claude Code or Codex, install the official Dograh setup skill and let your agent handle installation, configuration, and troubleshooting — it detects your OS, picks the right deploy path, runs Dograh's own setup scripts, and verifies the result.
# In Claude Code /plugin marketplace add dograh-hq/dograh-plugins /plugin install dograh@dograhThen start a new session and ask it to "set up Dograh" (or run
/dograh-setup). Codex is supported too — see the plugin repo.
Note
First startup may take 2-3 minutes to download all images. Once running, open http://localhost:3010 to create your first AI voice assistant! For common issues and solutions, see 🔧 Troubleshooting.
🎙️ Your First Voice Bot
- Open http://localhost:3010 in your browser.
- Pick Inbound or Outbound, name your bot (e.g. Lead Qualification), and describe the use case in 5–10 words (e.g. Screen insurance form submissions for purchase intent).
- Click Web Call — you're talking to your bot.
🔑 No API keys needed. Dograh ships with auto-generated keys and its own LLM / TTS / STT stack. Connect your own keys for LLM, TTS, STT, or Telephony (e.g. Twilio, Vonage, Telnyx) anytime.
Features
Voice Capabilities
- Telephony: Built-in telephony integration like Twilio, Vonage, Vobiz, Cloudonix (easily add others), with support for transferring calls to human agents
- Languages: English support (expandable to other languages)
- Custom Models: Bring your own TTS/STT models
- Real-time Processing: Low-latency voice interactions
Developer Experience
- Zero Config Start: Auto-generated API keys for instant testing
- Python-Based: Built on Python for easy customization
- Docker-First: Containerized for consistent deployments
- Modular Architecture: Swap components as needed
Testing & Quality
- Test Mode: Try your agent end-to-end before publishing, with no production calls or data affected
- In-Dashboard Web Calls: Talk to your bot directly while building — no telephony setup required
- QA Node: A built-in workflow node that analyzes prompt quality across your other nodes
Deployment Options
Local Development
Refer Local Setup
Self-Hosted Deployment
For detailed deployment instructions including remote server setup with HTTPS, see our Docker Deployment Guide.
Cloud Version
Visit https://www.dograh.com for our managed cloud offering.
📚Documentation
You can go to https://docs.dograh.com for our documentation.
📦 SDKs
- Python SDK — pypi.org/project/dograh-sdk
- Node SDK — npmjs.com/package/@dograh/sdk
🤝Community & Support
👋 Coming from the Better Stack video? Drop your use case in our pinned GitHub Discussion — we read every reply and the founders personally onboard early adopters.
- Slack — the cornerstone of Dograh AI contributions. Connect with maintainers, discuss features before coding, get help with setup, and stay current on contribution sprints.
- GitHub Discussions — share use cases, ask questions, swap workflow recipes.
- GitHub Issues — report bugs or request features.
👉 Join us → Dograh Community Slack
🙌 Contributing
We love contributions! Dograh AI is 100% open source and we intend to keep it that way.
Getting Started
- Fork the repository
- Create your feature branch (git checkout -b feature/AmazingFeature)
- Commit your changes (git commit -m 'Add some AmazingFeature')
- Push to the branch (git push origin feature/AmazingFeature)
- Open a Pull Request
⭐ Star History
📄 License
Dograh AI is licensed under the BSD 2-Clause License- the same license as projects that were used in building Dograh AI, ensuring compatibility and freedom to use, modify, and distribute.
🏢 About
Built with ❤️ by Dograh (Zansat Technologies Private Limited) Founded by YC alumni and exit founders committed to keeping voice AI open and accessible to everyone.