Skip to main content

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

StepStatusNotes
Stripe checkoutAutomatedWebhook creates premium_churches row
Magic link emailAutomatedSent after checkout
Admin dashboard accessAutomatedToken-based, works immediately
Telnyx number purchaseAutomatedprovisionVoiceLine() in webhook handler
LiveKit SIP trunk + dispatch ruleAutomatedprovisionVoiceLine() in webhook handler
church_voice_agents rowAutomatedCreated/updated by provisionVoiceLine()
PHONE_REGISTRY updateNot neededDB fallback covers new Telnyx numbers
organization_settings rowAutomatedFor bundle plans (voice + chat)
Test call verificationManualAgent 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:

  1. Greets the caller and explains they can try different demo churches
  2. Asks which type of church they want to experience
  3. 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_ID for 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

  1. When load_church_data() runs, it reads both calls_this_month and calls_limit from premium_churches (preferred) or church_voice_agents (fallback).

  2. If calls_limit > 0 and calls_this_month >= calls_limit:

    • load_church_data() returns None
    • get_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
  3. If the call is accepted, increment_call_count() bumps calls_this_month by 1 on the church_voice_agents row. This is non-fatal: if the increment fails, the church gets a free call rather than a dropped call.

  4. 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:

DataCache KeyTTLStale Fallback
Church configchurch:{church_id}5 minutesYes -- serves stale on DB error
Phone-to-church lookupphone:{to_number}5 minutesNo
Product knowledgepk:all15 minutesNo
Inline FAQsfaq:{church_id}5 minutesNo

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.