Knowledge > Products > Voice Agent > Provisioning
Voice Agent Provisioning
This document describes how a new church gets set up on the voice agent, what is automated today, what is manual, and how demo churches work.
New Church Setup (End to End)
1. Church purchases a voice plan
Pastor visits churchwiseai.com/pricing, selects a voice or bundle plan,
and completes Stripe checkout.
Voice plans: Voice Starter ($39.95/mo), Voice Pro ($69.95/mo)
Bundle plans: Starter Bundle ($49.95/mo), Pro Bundle ($79.95/mo),
Suite Bundle ($99.95/mo)
2. Stripe webhook fires
The webhook handler at /api/stripe/webhook processes the
checkout.session.completed event. It creates or updates a
premium_churches row with:
- church_id
- plan (voice_starter, voice_pro, starter_bundle, pro_bundle, suite_bundle)
- stripe_customer_id
- stripe_subscription_id
- admin_token (generated for magic link access)
3. Church receives magic link email
The admin receives an email with a link to:
churchwiseai.com/admin/[admin_token]
This gives them access to the admin dashboard where they can
manage their voice agent settings, view call logs, etc.
4. **AUTOMATED (as of April 2026): Voice line provisioning fires from the Stripe webhook**
When a voice or bundle plan is purchased, the webhook at `/api/stripe/webhook` calls
`provisionVoiceLine()` (in `churchwiseai-web/src/lib/voice-provision.ts`) automatically:
a. Buys a Telnyx phone number in the church's area code
- Tries friendly patterns (area code + "000", "400", "500" etc.)
- Falls back to any available number in the area code
- Stores number in `church_voice_agents.twilio_phone_number` (column name is legacy)
b. Creates a LiveKit SIP inbound trunk for the number
c. Creates a LiveKit SIP dispatch rule pointing to the `churchwiseai-voice` agent
d. Updates `church_voice_agents` row with the new number and trunk config
e. If provisioning fails, sends a founder email alert (never silently fails)
f. If bundle plan: also provisions organization_settings for the chatbot
**Manual fallback:** If auto-provisioning fails, an agent can use the admin API:
- `POST /api/admin/provision-number` with `{ adminToken, mode: "auto" }` — buys + wires a new number
- `POST /api/admin/provision-number` with `{ adminToken, mode: "register", existingNumber }` — wires an existing number
**PHONE_REGISTRY in session.py** (optional): The static registry maps phone numbers to church IDs for fast routing. New Telnyx numbers use DB fallback automatically without needing a PHONE_REGISTRY entry.
5. Done -- multi-tenant routing handles the rest
No deployment needed. No container to spin up. The next time someone
calls the Twilio number, the call forwards to Cartesia, get_agent()
resolves the church, loads the config from Supabase, and builds a
personalized agent on the fly.
6. First call verification
The agent or founder should make a test call to verify:
- Correct church name in the greeting
- Correct denomination/theological vocabulary
- Tools work (try submitting a prayer request)
- Notification emails arrive
- Call appears in admin dashboard call log
What Is Automated vs. Manual Today
| Step | Status | Notes |
|---|---|---|
| Stripe checkout | Automated | Webhook creates premium_churches row |
| Magic link email | Automated | Sent after checkout |
| Admin dashboard access | Automated | Token-based, works immediately |
| Telnyx number purchase | Automated | provisionVoiceLine() in webhook handler |
| LiveKit SIP trunk + dispatch rule | Automated | provisionVoiceLine() in webhook handler |
| church_voice_agents row | Automated | Created/updated by provisionVoiceLine() |
| PHONE_REGISTRY update | Not needed | DB fallback covers new Telnyx numbers |
| organization_settings row | Automated | For bundle plans (voice + chat) |
| Test call verification | Manual | Agent or founder should verify after provisioning |
Legacy Twilio lines (existing 4 numbers on the main trunk) remain on Twilio. All new customers get Telnyx numbers provisioned automatically.
Demo Church Setup
Three demo churches are configured for sales demonstrations and testing:
Grace Community Church (Protestant Demo)
DEMO_CHURCH_ID = "00000000-0000-4000-a000-000000000001"
- Non-denominational Protestant church
- Full tool suite enabled (prayer, callback, visitor, events, giving)
- Used as the primary demo during sales calls
- Pre-loaded with sample FAQs, service times, staff directory
St. Joseph Catholic Parish (Catholic Demo)
DEMO_CATHOLIC_CHURCH_ID = "00000000-0000-4000-a000-000000000002"
- Roman Catholic parish
- Theological lens ID 7 (Catholic tradition)
- Demonstrates denomination-aware vocabulary (Mass, Eucharist, parish, etc.)
- Shows that the same agent adapts to different traditions
Demo Router
When someone calls a demo line number (listed in DEMO_NUMBERS in session.py), they reach the Demo Router Agent instead of going directly to a specific church. The Demo Router:
- Greets the caller and explains they can try different demo churches
- Asks which type of church they want to experience
- Transfers to the appropriate demo church agent via handoff
Current demo line numbers:
- +14696152221 (US demo line)
- +13658254095 (CA demo line)
- +13186678328 (Cartesia agent -- demo lines forward here)
Sales Agent
The toll-free number (+18886030316) and any unassigned/unknown numbers route to the Sales Agent. The Sales Agent:
- Explains ChurchWiseAI products and pricing
- Loads product_knowledge table for accurate answers
- Can transfer to demo churches to let prospects experience the product
- Uses
SALES_SENTINEL_CHURCH_IDfor call logging
Call Limit Enforcement
Each church has a monthly call limit based on their plan tier:
calls_this_month: current count (incremented on each call)
calls_limit: maximum allowed per month (0 = unlimited)
How It Works
-
When
load_church_data()runs, it reads bothcalls_this_monthandcalls_limitfrompremium_churches(preferred) orchurch_voice_agents(fallback). -
If
calls_limit > 0andcalls_this_month >= calls_limit:load_church_data()returnsNoneget_agent()sees the None result and falls back to the Sales Agent- The caller reaches the Sales Agent instead of the church's agent
- The Sales Agent does not explain the limit -- it simply handles the call as a sales inquiry
-
If the call is accepted,
increment_call_count()bumpscalls_this_monthby 1 on thechurch_voice_agentsrow. This is non-fatal: if the increment fails, the church gets a free call rather than a dropped call. -
The monthly counter (
calls_this_month) needs to be reset to 0 at the start of each billing cycle. This is currently a manual reset or scheduled database job.
Call Limits by Plan
Call limits are configured per-church in the calls_limit column. The intended limits by plan tier are set during provisioning. Setting calls_limit to 0 means unlimited calls.
Caching Strategy
The provisioning system uses aggressive caching to minimize database load during calls:
| Data | Cache Key | TTL | Stale Fallback |
|---|---|---|---|
| Church config | church:{church_id} | 5 minutes | Yes -- serves stale on DB error |
| Phone-to-church lookup | phone:{to_number} | 5 minutes | No |
| Product knowledge | pk:all | 15 minutes | No |
| Inline FAQs | faq:{church_id} | 5 minutes | No |
When a church updates their settings in the admin dashboard, the changes take effect within the cache TTL window (typically under 5 minutes). There is no cache invalidation mechanism -- changes propagate naturally when the cache expires.