Financial Services & Banking

Customer Onboarding

Welcome new account holders, walk them through regulatory disclosures, collect preferences for paperless statements and overdraft protection, confirm debit card delivery address, and optionally set up a security question — all in a single call.

Why this matters

PCI-compliant, fully auditable voice automation for loans, collections, onboarding, and fraud prevention. This example shows you how to automate customer onboarding calls end-to-end with Guava's SDK — no telephony plumbing, no prompt engineering, just Python.

How to set persona & task
Working with Fields and Say items
Handling callbacks
Running the agent
Step 01

Installation

Install from Guava's private PyPI index. A public package is coming soon — the install command will simplify to pip install guava.

terminal
# Step 1: Install Guava
pip install gridspace-guava --extra-index-url https://guava-pypi.gridspace.com

# Public PyPI package coming soon — the install command will simplify to:
# pip install guava

# Step 2: Set your credentials
export GUAVA_API_KEY="..."
export GUAVA_AGENT_NUMBER="..."
Step 02

How it's built

Every Guava agent is a Python class. Walk through the key sections below, then grab the complete file at the end.

01

Imports

Import the Guava SDK and any helpers you need. guava.CallController is the base class for every voice agent.

example.py
# Install: pip install gridspace-guava --extra-index-url https://guava-pypi.gridspace.com
import guava
import os
import json
from datetime import datetime
02

Agent setup

set_persona() defines how the agent presents itself. set_task() gives it its mission in plain English. The checklist drives the conversation — Guava works through it top-to-bottom, collecting Field values and speaking Say items as it goes.

example.py
class CustomerOnboardingController(guava.CallController):
    def __init__(self, contact_name: str, account_type: str):
        super().__init__()
        self.contact_name = contact_name
        self.account_type = account_type
        self.set_persona(
            organization_name="First National Bank",
            agent_name="Jamie",
            agent_purpose=(
                f"to walk a new customer through the setup of their {self.account_type}, "
                f"deliver required disclosures, and configure initial account preferences"
            ),
        )
        self.reach_person(
            contact_full_name=self.contact_name,
            on_success=self.begin_onboarding,
            on_failure=self.recipient_unavailable,
        )

    def begin_onboarding(self):
        self.set_task(
            objective=(
                f"You are onboarding {self.contact_name} as a new First National Bank customer. "
                f"They have just opened a {self.account_type}. Your goal is to welcome them, "
                f"walk them through required regulatory disclosures, collect their preferences for "
                f"paperless statements and overdraft protection, confirm their debit card delivery "
                f"address, and optionally set up a security question for their online banking "
                f"profile. Be warm, clear, and patient — many customers are unfamiliar with these "
                f"steps. Confirm each selection back to the customer before moving on."
            ),
            checklist=[
                guava.Say(
                    f"Hello {self.contact_name}, congratulations on opening your new "
                    f"{self.account_type} with First National Bank! My name is Jamie and I am "
                    f"here to help you get everything set up today. This should only take a few "
                    f"minutes, and I will walk you through each step."
                ),
                guava.Say(
                    "Before we get started with your preferences, I am required to share a few "
                    "important disclosures with you. Please listen carefully. By opening this "
                    "account, you agree to the Deposit Account Agreement and the Fee Schedule, "
                    "both of which are available on our website and will be mailed to you within "
                    "7 business days. Your deposits are insured by the FDIC up to $250,000. "
                    "Standard account terms, including any applicable monthly service fees and "
                    "minimum balance requirements, apply as outlined in your account agreement."
                ),
                guava.Field(
                    key="disclosures_acknowledged",
                    description=(
                        "Confirm that the customer has heard and acknowledged the required account "
                        "disclosures including the Deposit Account Agreement, Fee Schedule, and "
                        "FDIC insurance information. Record a brief note of their acknowledgment."
                    ),
                    field_type="text",
                    required=True,
                ),
                guava.Say(
                    "Next, would you like to enroll in paperless statements? With paperless "
                    "statements, your monthly statements will be delivered securely to your email "
                    "instead of by mail. You can switch back at any time through online banking."
                ),
                guava.Field(
                    key="paperless_statements_opted_in",
                    description=(
                        "Record whether the customer chose to opt in to paperless statements. "
                        "Expected values: 'yes' to enroll or 'no' to continue receiving paper statements."
                    ),
                    field_type="text",
                    required=True,
                ),
                guava.Say(
                    "Would you also like to add overdraft protection to your account? Overdraft "
                    "protection allows transactions to go through even if your balance is "
                    "temporarily low, which can help you avoid declined transactions or returned "
                    "payments. A small fee may apply per covered transaction."
                ),
                guava.Field(
                    key="overdraft_protection_opted_in",
                    description=(
                        "Record whether the customer chose to opt in to overdraft protection. "
                        "Expected values: 'yes' to enroll or 'no' to decline."
                    ),
                    field_type="text",
                    required=True,
                ),
                guava.Say(
                    "Your debit card will be mailed to the address we have on file. I want to "
                    "quickly confirm that address is correct before we proceed."
                ),
                guava.Field(
                    key="debit_card_delivery_address_confirmed",
                    description=(
                        "Read back the address on file to the customer and ask them to confirm it "
                        "is correct for debit card delivery. Record 'confirmed' if they verify the "
                        "address is correct, or record the corrected address they provide."
                    ),
                    field_type="text",
                    required=True,
                ),
                guava.Field(
                    key="security_question_set",
                    description=(
                        "Ask the customer if they would like to set up a security question for "
                        "their online banking profile now, or if they prefer to do this later "
                        "through the mobile app. Record 'set_during_call' if a security question "
                        "was established, 'deferred' if they chose to do it later, or leave blank "
                        "if the topic was not addressed."
                    ),
                    field_type="text",
                    required=False,
                ),
            ],
            on_complete=self.save_results,
        )

    def save_results(self):
        results = {
            "timestamp": datetime.utcnow().isoformat() + "Z",
            "contact_name": self.contact_name,
            "account_type": self.account_type,
            "disclosures_acknowledged": self.get_field("disclosures_acknowledged"),
            "paperless_statements_opted_in": self.get_field("paperless_statements_opted_in"),
            "overdraft_protection_opted_in": self.get_field("overdraft_protection_opted_in"),
            "debit_card_delivery_address_confirmed": self.get_field(
                "debit_card_delivery_address_confirmed"
            ),
            "security_question_set": self.get_field("security_question_set"),
        }
        print(json.dumps(results, indent=2))
        self.hangup(
            final_instructions=(
                f"Congratulate {self.contact_name} on completing their account setup. Provide a "
                f"brief summary of their selections: disclosures acknowledged, paperless statement "
                f"preference, overdraft protection choice, and debit card delivery address. Let "
                f"them know their debit card will arrive within 5 to 7 business days and that they "
                f"can begin using online and mobile banking immediately. Share the customer service "
                f"number for any questions and close the call warmly, welcoming them to First "
                f"National Bank."
            )
        )

    def recipient_unavailable(self):
        self.hangup(
            final_instructions=(
                f"You were unable to reach {self.contact_name}. Leave a warm, welcoming voicemail "
                f"identifying yourself as Jamie from First National Bank. Congratulate them on "
                f"opening their new {self.account_type} and let them know you were calling to help "
                f"complete their account setup. Ask them to call back at their convenience or visit "
                f"the bank's website to complete the setup steps online."
            )
        )
03

Run it

Create a Client and hand it an instance of your agent. accept_call() blocks and waits for an inbound call; swap it for reach_person() to make outbound calls instead.

example.py
if __name__ == "__main__":
    guava.Client().create_outbound(
        from_number=os.environ["GUAVA_AGENT_NUMBER"],
        to_number="+1...",
        call_controller=CustomerOnboardingController("Sophia Nguyen", "checking account"),
    )

Platform performance

<1s

Response time

99.99%

Uptime SLA

13+

Industries served

Step 03

Full example

The complete file — copy it, save it as example.py, and run it.

example.py
# Install: pip install gridspace-guava --extra-index-url https://guava-pypi.gridspace.com
import guava
import os
import json
from datetime import datetime

class CustomerOnboardingController(guava.CallController):
    def __init__(self, contact_name: str, account_type: str):
        super().__init__()
        self.contact_name = contact_name
        self.account_type = account_type
        self.set_persona(
            organization_name="First National Bank",
            agent_name="Jamie",
            agent_purpose=(
                f"to walk a new customer through the setup of their {self.account_type}, "
                f"deliver required disclosures, and configure initial account preferences"
            ),
        )
        self.reach_person(
            contact_full_name=self.contact_name,
            on_success=self.begin_onboarding,
            on_failure=self.recipient_unavailable,
        )

    def begin_onboarding(self):
        self.set_task(
            objective=(
                f"You are onboarding {self.contact_name} as a new First National Bank customer. "
                f"They have just opened a {self.account_type}. Your goal is to welcome them, "
                f"walk them through required regulatory disclosures, collect their preferences for "
                f"paperless statements and overdraft protection, confirm their debit card delivery "
                f"address, and optionally set up a security question for their online banking "
                f"profile. Be warm, clear, and patient — many customers are unfamiliar with these "
                f"steps. Confirm each selection back to the customer before moving on."
            ),
            checklist=[
                guava.Say(
                    f"Hello {self.contact_name}, congratulations on opening your new "
                    f"{self.account_type} with First National Bank! My name is Jamie and I am "
                    f"here to help you get everything set up today. This should only take a few "
                    f"minutes, and I will walk you through each step."
                ),
                guava.Say(
                    "Before we get started with your preferences, I am required to share a few "
                    "important disclosures with you. Please listen carefully. By opening this "
                    "account, you agree to the Deposit Account Agreement and the Fee Schedule, "
                    "both of which are available on our website and will be mailed to you within "
                    "7 business days. Your deposits are insured by the FDIC up to $250,000. "
                    "Standard account terms, including any applicable monthly service fees and "
                    "minimum balance requirements, apply as outlined in your account agreement."
                ),
                guava.Field(
                    key="disclosures_acknowledged",
                    description=(
                        "Confirm that the customer has heard and acknowledged the required account "
                        "disclosures including the Deposit Account Agreement, Fee Schedule, and "
                        "FDIC insurance information. Record a brief note of their acknowledgment."
                    ),
                    field_type="text",
                    required=True,
                ),
                guava.Say(
                    "Next, would you like to enroll in paperless statements? With paperless "
                    "statements, your monthly statements will be delivered securely to your email "
                    "instead of by mail. You can switch back at any time through online banking."
                ),
                guava.Field(
                    key="paperless_statements_opted_in",
                    description=(
                        "Record whether the customer chose to opt in to paperless statements. "
                        "Expected values: 'yes' to enroll or 'no' to continue receiving paper statements."
                    ),
                    field_type="text",
                    required=True,
                ),
                guava.Say(
                    "Would you also like to add overdraft protection to your account? Overdraft "
                    "protection allows transactions to go through even if your balance is "
                    "temporarily low, which can help you avoid declined transactions or returned "
                    "payments. A small fee may apply per covered transaction."
                ),
                guava.Field(
                    key="overdraft_protection_opted_in",
                    description=(
                        "Record whether the customer chose to opt in to overdraft protection. "
                        "Expected values: 'yes' to enroll or 'no' to decline."
                    ),
                    field_type="text",
                    required=True,
                ),
                guava.Say(
                    "Your debit card will be mailed to the address we have on file. I want to "
                    "quickly confirm that address is correct before we proceed."
                ),
                guava.Field(
                    key="debit_card_delivery_address_confirmed",
                    description=(
                        "Read back the address on file to the customer and ask them to confirm it "
                        "is correct for debit card delivery. Record 'confirmed' if they verify the "
                        "address is correct, or record the corrected address they provide."
                    ),
                    field_type="text",
                    required=True,
                ),
                guava.Field(
                    key="security_question_set",
                    description=(
                        "Ask the customer if they would like to set up a security question for "
                        "their online banking profile now, or if they prefer to do this later "
                        "through the mobile app. Record 'set_during_call' if a security question "
                        "was established, 'deferred' if they chose to do it later, or leave blank "
                        "if the topic was not addressed."
                    ),
                    field_type="text",
                    required=False,
                ),
            ],
            on_complete=self.save_results,
        )

    def save_results(self):
        results = {
            "timestamp": datetime.utcnow().isoformat() + "Z",
            "contact_name": self.contact_name,
            "account_type": self.account_type,
            "disclosures_acknowledged": self.get_field("disclosures_acknowledged"),
            "paperless_statements_opted_in": self.get_field("paperless_statements_opted_in"),
            "overdraft_protection_opted_in": self.get_field("overdraft_protection_opted_in"),
            "debit_card_delivery_address_confirmed": self.get_field(
                "debit_card_delivery_address_confirmed"
            ),
            "security_question_set": self.get_field("security_question_set"),
        }
        print(json.dumps(results, indent=2))
        self.hangup(
            final_instructions=(
                f"Congratulate {self.contact_name} on completing their account setup. Provide a "
                f"brief summary of their selections: disclosures acknowledged, paperless statement "
                f"preference, overdraft protection choice, and debit card delivery address. Let "
                f"them know their debit card will arrive within 5 to 7 business days and that they "
                f"can begin using online and mobile banking immediately. Share the customer service "
                f"number for any questions and close the call warmly, welcoming them to First "
                f"National Bank."
            )
        )

    def recipient_unavailable(self):
        self.hangup(
            final_instructions=(
                f"You were unable to reach {self.contact_name}. Leave a warm, welcoming voicemail "
                f"identifying yourself as Jamie from First National Bank. Congratulate them on "
                f"opening their new {self.account_type} and let them know you were calling to help "
                f"complete their account setup. Ask them to call back at their convenience or visit "
                f"the bank's website to complete the setup steps online."
            )
        )

if __name__ == "__main__":
    guava.Client().create_outbound(
        from_number=os.environ["GUAVA_AGENT_NUMBER"],
        to_number="+1...",
        call_controller=CustomerOnboardingController("Sophia Nguyen", "checking account"),
    )
Step 04

Run it

Start the agent. It will connect to Guava's infrastructure and begin accepting calls on your assigned number.

terminal
python example.py
Get Started