Documentation | Guava

Outbound Campaigns

While you can use agent.call_phone("+1...") to place singular outbound calls, we recommend using Campaigns when calling multiple contacts.

Campaigns automatically manage missed-call retries, enforce calling windows, and control call concurrency. Since they are persistent resources, you should create one Campaign for each distinct use case and continue adding contacts to it as needed.

While Campaigns are responsible for dispatching calls - you will still need to "attach" an Agent to handle the call itself - this is done using a unique "code" created for each Campaign.

Before you start

You'll need:

Create a campaign in the dashboard

Open the Campaigns page and click Create Campaign. Configure your campaign name, origin phone numbers, calling windows, and retry settings.

Once created, take note of the campaign code — it starts with gcmp-....

Upload contacts

From the campaign's detail page in the dashboard, upload your contact list. Each contact needs a phone number and any per-call data variables your agent will use (such as a patient name or appointment time).

These variables will be accessible inside your agent callbacks via call.get_variable().

Write your agent

Define an Agent and attach callbacks for each stage of the call.

import guava
from guava import Agent, Field

agent = Agent(
    name="Sarah",
    organization="Valley Dental",
    purpose="Remind patients about their upcoming dental appointments.",
)

@agent.on_call_start
def on_call_start(call: guava.Call):
    call.reach_person(
        contact_full_name=call.get_variable("patient_name"),
    )

@agent.on_reach_person
def on_reach_person(call: guava.Call, outcome: str):
    if outcome == "available":
        call.add_info("appointment_details", {
            "patient_name": call.get_variable("patient_name"),
            "appointment_date": call.get_variable("appointment_date"),
            "appointment_time": call.get_variable("appointment_time")
        })

call.set_task(
            "confirm_appointment",
            objective="Confirm the appointment date and time.",
            checklist=[
                Field(
                    key="appointment_response",
                    description="Whether the patient confirms, reschedules, or cancels",
                    field_type="multiple_choice",
                    choices=["confirmed", "reschedule", "cancel"],
                ),
            ],
        )
    else:
        call.hangup()

@agent.on_task_complete("confirm_appointment")
def on_confirmed(call: guava.Call):
    call.hangup("Thank them and end the call.")

Test your agent

Before attaching to a campaign, test your agent using agent.call_local() or agent.chat(). Pass a variables dict to simulate per-contact data:

agent.chat(variables={
    "patient_name": "Jane Smith",
    "appointment_date": "Monday, June 23rd",
    "appointment_time": "2:00 PM",
})

Attach and serve the campaign

Next, run agent.attach_campaign("gcmp-..."). This "attaches" your agent to the Campaign that we previously created.

agent.attach_campaign(campaign_code="gcmp-...")

Review calls in the dashboard

Once your campaign is running, visit the Campaigns page to monitor progress.

Questions? hi@goguava.ai

Guava is an API for building natural and reliable voice agents. All of our docs can be downloaded in plain-text form.