Different scope from the Run-State Journal. The inbound journal deduplicates and recovers webhook messages. The run-state journal persists the execution cursor of a single run. A webhook may spawn a run; the two journals track the two halves of the pipeline.
On by default for gateway/bot runs — Every bot started via
praisonai bot start, onboard, or bot.yaml gets the journal automatically. No code needed. The journal lives at ~/.praisonai/state/<platform>/ingress.sqlite. Set delivery.durable: false to opt out.Default behavior (no config needed)
Every bot started throughbuild_session_manager (all shipped adapters) automatically gets an Inbound Journal at:
~/.praisonai/state/telegram/ingress.sqlite. A Discord bot uses ~/.praisonai/state/discord/ingress.sqlite. Each platform is fully isolated — no cross-platform dedup collisions.
Set PRAISONAI_HOME to override the base directory:
Opt out or override path
Add adelivery: block to any channel in your bot.yaml or gateway.yaml:
Quick Start (advanced: manual setup)
Most users get the journal automatically. For custom setups outsidebuild_session_manager:
1
Create journal that survives restarts
2
Enable on your bot
You don’t need to call
complete() yourself when using BotSessionManager.chat() — successful chats mark the journal entry as completed automatically. You only need to call complete() manually if you’re driving InboundJournal directly without BotSessionManager.How It Works
Before PR #1980, the default
chat() path claimed entries but never called complete(). On startup, journal.replay() could re-issue messages the user had already received answers to. Upgrade to a release after 2026-06-19 — replay then only covers genuinely incomplete entries.When to use which option
Configuration Options
Per-platform examples
- Telegram
- Discord
- Slack
- WhatsApp
- Email
- AgentMail
Common Patterns
Pattern 1: Dedup-only (webhook redelivery protection)
Pattern 2: Crash recovery + replay loop on startup
Pattern 3: Combining with InboundDLQ for full durability stack
Best Practices
Use the same path across restarts
Use the same path across restarts
The journal’s SQLite file must survive restarts for crash recovery to work. Use an absolute path or a location that persists across deployments.
Tune claim_timeout to match your agent latency
Tune claim_timeout to match your agent latency
Set
claim_timeout to be longer than your p99 agent.chat() latency to avoid false stale entry detection.Call journal.replay() in your bot's startup hook
Call journal.replay() in your bot's startup hook
Always replay stale entries when your bot starts to recover from crashes.
Keep account stable per bot instance
Keep account stable per bot instance
The
account parameter is part of the deduplication key. Keep it consistent for each bot instance.Set claim_timeout below the platform's redelivery window
Set claim_timeout below the platform's redelivery window
Platforms redeliver webhooks at fixed intervals (Telegram retries within seconds, Slack waits ~3s before its first retry, etc.). Set
claim_timeout shorter than your platform’s redelivery window so that a crashed worker’s claim becomes stale before the next redelivery arrives — that’s what enables automatic recovery without a restart.Related
Delivery Config
Full reference for the
delivery: channel config block — defaults, opt-out, and path overrideInbound DLQ
Failure-side durability when agent execution fails
Durable Outbound Delivery
Outbound counterpart — persist outgoing messages with retry and idempotency
Bot Routing
Multi-channel session routing for complex bot setups

