diff --git a/fern/call-forwarding.mdx b/fern/call-forwarding.mdx
index 15c14143..7403a69e 100644
--- a/fern/call-forwarding.mdx
+++ b/fern/call-forwarding.mdx
@@ -18,9 +18,21 @@ Vapi's call forwarding functionality allows you to redirect calls to different p
## Setting Up Call Forwarding
-### 1. Defining Destinations and Messages
+### 1. Create a Transfer Call Tool in the Dashboard
-The `transferCall` tool includes a list of destinations and corresponding messages to notify the caller:
+The recommended approach is to create your transfer call tool in the Vapi dashboard:
+
+1. Navigate to **Tools** in your Vapi dashboard
+2. Click **Create Tool**
+3. Select **Transfer Call** as the tool type
+4. Configure your destinations:
+ - **Department A**: `+1234567890` with message "I am forwarding your call to Department A. Please stay on the line."
+ - **Department B**: `+0987654321` with message "I am forwarding your call to Department B. Please stay on the line."
+ - **Department C**: `+1122334455` with message "I am forwarding your call to Department C. Please stay on the line."
+
+### 2. Alternative: API Configuration
+
+You can also define the tool via API with destinations and corresponding messages:
```json
{
@@ -112,7 +124,7 @@ You can also specify the `extension` parameter to forward the call to an extensi
]
```
-### 2. Using the `transferCall` Function
+### 3. Using the `transferCall` Function
When the assistant needs to forward a call, it uses the `transferCall` function with the appropriate destination:
@@ -127,7 +139,7 @@ When the assistant needs to forward a call, it uses the `transferCall` function
}
```
-### 3. Customizing Messages
+### 4. Customizing Messages
Customize the messages for each destination to provide clear information to the caller:
diff --git a/fern/docs.yml b/fern/docs.yml
index a5a98472..362282bf 100644
--- a/fern/docs.yml
+++ b/fern/docs.yml
@@ -116,12 +116,18 @@ navigation:
- page: Inbound support
path: examples/inbound-support.mdx
icon: fa-light fa-phone-volume
+ - page: Appointment scheduling
+ path: examples/appointment-scheduling.mdx
+ icon: fa-light fa-calendar-check
- page: Outbound sales
path: examples/outbound-sales.mdx
icon: fa-light fa-money-bill-wave
- - page: Pizza website
- path: examples/pizza-website.mdx
- icon: fa-light fa-pizza-slice
+ - page: Medical triage
+ path: examples/clinic-triage-scheduling.mdx
+ icon: fa-light fa-stethoscope
+ - page: Order management
+ path: examples/ecommerce-order-management.mdx
+ icon: fa-light fa-shopping-cart
- page: Voice widget
path: examples/voice-widget.mdx
icon: fa-light fa-window-maximize
@@ -719,7 +725,9 @@ redirects:
- source: "/technical_support"
destination: "/examples/inbound-support"
- source: "/pizza_website"
- destination: "/examples/pizza-website"
+ destination: "/examples/inbound-support"
+ - source: "/examples/pizza-website"
+ destination: "/examples/inbound-support"
- source: "/outbound_call_python"
destination: "/examples/outbound-call-python"
- source: "/voice_widget"
diff --git a/fern/examples/appointment-scheduling.mdx b/fern/examples/appointment-scheduling.mdx
new file mode 100644
index 00000000..17ce1421
--- /dev/null
+++ b/fern/examples/appointment-scheduling.mdx
@@ -0,0 +1,266 @@
+---
+title: Appointment scheduling workflow
+subtitle: Build an AI receptionist workflow that schedules, reschedules, and cancels appointments using visual nodes.
+slug: examples/appointment-scheduling
+description: Build a voice AI appointment scheduling workflow with calendar integration, availability checking, and automated confirmations using Vapi's workflow builder.
+---
+
+## Overview
+
+Build an AI-powered appointment scheduling workflow that handles inbound calls for booking, rescheduling, and canceling appointments. The workflow uses visual nodes to create branching logic, integrates with calendar systems, checks availability in real-time, and sends confirmation messages.
+
+**What You'll Build:**
+* Visual workflow with branching appointment logic
+* Real-time calendar integration and availability checking
+* Customer database with automated confirmations
+* Global nodes for error handling and validation
+* 24/7 phone booking with conditional routing
+
+## Prerequisites
+
+* A [Vapi account](https://dashboard.vapi.ai/).
+* A Google Calendar account (or other calendar service).
+
+## Scenario
+
+We will be creating an appointment scheduling workflow for Tony's Barbershop, a traditional barbershop that wants to automate their phone booking process with sophisticated branching logic to handle different appointment scenarios.
+
+---
+
+## 1. Create a Knowledge Base
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ In your Vapi dashboard, click `Files` in the left sidebar.
+
+
+ - Click `Choose file`. Upload all three CSV files: `services.csv`, `customers.csv`, and `appointments.csv`.
+ - Note the file IDs. We'll need them later to create tools.
+
+
+
+
+
+---
+
+## 2. Create a Workflow
+
+
+
+ Go to [dashboard.vapi.ai](https://dashboard.vapi.ai) and log in to your account.
+
+
+ Click `Workflows` in the left sidebar.
+
+
+ - Click `Create Workflow`.
+ - Enter workflow name: `Barbershop Appointment Workflow`.
+ - Select the default template (includes Call Start node).
+ - Click "Create Workflow".
+
+
+ - Configure workflow variables for customer data and appointment information
+
+
+
+
+
+---
+
+## 3. Build the Workflow
+
+You'll start with a default template that includes a "Call Start" node. We'll modify the existing nodes and add new ones to create our appointment scheduling workflow.
+
+
+
+ The default template includes a conversation node. Click on it and configure:
+
+ **First Message**:
+ ```txt
+ Hello! Thank you for calling Tony's Barbershop. This is Sarah, your booking assistant. I can help you schedule, reschedule, or cancel appointments. How can I help you today?
+ ```
+
+ **Prompt**:
+ ```txt
+ You are Sarah, the friendly booking assistant for Tony's Barbershop.
+
+ Listen to the customer's response and determine their intent:
+ - "schedule" for new appointments
+ - "reschedule" for changing existing appointments
+ - "cancel" for canceling appointments
+ - "status" for checking appointment details
+ - "other" for anything else
+
+ Keep responses under 35 words. Ask clarifying questions if intent is unclear.
+ ```
+
+ **Extract Variables**:
+ - Variable: `intent`
+ - Type: `String`
+ - Description: `The customer's primary intent`
+ - Enum Values: `schedule`, `reschedule`, `cancel`, `status`, `other`
+
+
+
+ Click the + button below the greeting node and add a new **Conversation** node:
+
+ **Prompt**:
+ ```txt
+ Now I need to verify your information. Can you please provide your phone number or full name so I can look up your account?
+
+ If they provide a phone number, extract it. If they provide a name, extract it.
+ Be friendly and reassuring about privacy.
+ ```
+
+ **Extract Variables**:
+ - Variable: `phone_number`
+ - Type: `String`
+ - Description: `Customer's phone number if provided`
+ - Variable: `customer_name`
+ - Type: `String`
+ - Description: `Customer's full name if provided`
+
+
+
+ Add a **Tool** node:
+
+ **Select Tool**: Choose your pre-configured customer lookup tool from the dropdown. This tool will use the extracted `phone_number` and `customer_name` variables to find the customer in your database.
+
+
+
+ Create branching paths based on the customer's intent. Add multiple conversation nodes:
+
+ **Schedule New Appointment Node**:
+ - **Prompt**: `Great! I can help you schedule a new appointment. What type of service would you like? We offer haircuts, beard trims, shampoo and styling, and full grooming packages.`
+
+ **Reschedule Appointment Node**:
+ - **Prompt**: `I can help you reschedule your appointment. Let me first look up your current booking details.`
+
+ **Cancel Appointment Node**:
+ - **Prompt**: `I can help you cancel your appointment. Let me look up your current booking to confirm the details.`
+
+
+
+ Connect the nodes with conditional edges:
+
+ **To Schedule Appointment Node**:
+ - Condition: `if the user said yes` (AI condition)
+ - Alternative: `{{ intent == "schedule" }}` (Logic condition)
+
+ **To Reschedule Appointment Node**:
+ - Condition: `if the user said yes` (AI condition)
+ - Alternative: `{{ intent == "reschedule" }}` (Logic condition)
+
+ **To Cancel Appointment Node**:
+ - Condition: `if the user said yes` (AI condition)
+ - Alternative: `{{ intent == "cancel" }}` (Logic condition)
+
+
+
+ Create a global conversation node that checks for errors after every step:
+
+ **Enable Global Node**: Toggle this on to make the node available from any point in the conversation
+
+ **Prompt**:
+ ```txt
+ I apologize for any confusion. Let me transfer you to one of our human staff members who can better assist you. Please hold for just a moment.
+ ```
+
+ This global node will activate whenever there's an error or the customer becomes frustrated, regardless of where they are in the workflow.
+
+
+
+ For the schedule appointment flow, add these nodes:
+
+ **Service Selection Node** (Conversation):
+ - **Prompt**: `What type of service would you like to book? Also, do you have a preferred date and time?`
+ - **Extract Variables**: `service_type`, `preferred_date`, `preferred_time`
+
+ **Availability Check Tool Node**:
+ - **Select Tool**: Choose "Check Availability" from the pre-defined calendar tools
+ - This will automatically check available slots based on the extracted preferences
+
+ **Availability Results Node** (Conversation):
+ - **Prompt**: `Based on your preferences, here are the available time slots. Which one works best for you?`
+ - Use conditional logic to offer alternatives if preferred time unavailable
+
+
+
+ **Booking Confirmation Node** (Conversation):
+ - **Prompt**: `Perfect! Let me confirm your appointment details: [service] on [date] at [time]. Is this correct?`
+ - **Extract Variables**: `confirmation_status`
+
+ **Create Appointment Tool Node**:
+ - **Select Tool**: Choose "Schedule Event" from the pre-defined calendar tools
+ - This will book the appointment in your calendar system
+
+ **Send Confirmation Node** (Tool):
+ - **Select Tool**: Choose your pre-configured SMS/email confirmation tool
+
+ **Completion Node** (Conversation):
+ - **Prompt**: `Great! Your appointment is confirmed. You'll receive a confirmation message shortly. Is there anything else I can help you with today?`
+
+
+
+ **Transfer to Human Node**:
+ - **Node Type**: `Transfer Call`
+ - **Phone to transfer to**: `+1-555-BARBER-1` (your barbershop number)
+
+ **End Call Node**:
+ - **Node Type**: `End Call`
+ - **First Message**: `Thank you for calling Tony's Barbershop. Have a great day!`
+ - Use when customer is satisfied and no further assistance needed
+
+
+
+---
+
+## 4. Configure Phone Number
+
+
+
+ Click `Phone Numbers` in the left sidebar of your dashboard.
+
+
+ - Click `Create Phone Number` for a new Vapi number, or
+ - Click `Import Phone Number` to use your existing number from Twilio/Telnyx
+
+
+ **Workflow**: Select your `Barbershop Appointment Workflow`
+
+ **Advanced Settings**:
+ - Enable call recording for quality assurance
+ - Set maximum call duration (e.g., 15 minutes)
+ - Configure voicemail detection if needed
+
+
+ Call your Vapi phone number to test the complete workflow:
+ - Test different appointment scenarios
+ - Verify branching logic works correctly
+ - Ensure global nodes trigger appropriately
+ - Test error handling and recovery flows
+
+
+
+## Next Steps
+
+Just like that, you've built an automated appointment scheduling workflow that can handle inbound calls, manage bookings, and provide 24/7 availability for your barbershop.
+
+Consider reading the following guides to further enhance your workflow:
+
+* [**Custom Tools**](/tools/custom-tools) - Create custom tools for calendar integration and customer management.
+* [**Voice Formatting Plan**](/assistants/voice-formatting-plan) - Configure speech formatting for clear appointment communication.
+* [**Dynamic Variables**](/assistants/dynamic-variables) - Use variables to personalize appointment confirmations.
diff --git a/fern/examples/clinic-triage-scheduling.mdx b/fern/examples/clinic-triage-scheduling.mdx
new file mode 100644
index 00000000..4d4caa17
--- /dev/null
+++ b/fern/examples/clinic-triage-scheduling.mdx
@@ -0,0 +1,374 @@
+---
+title: Clinic triage and scheduling workflow
+subtitle: Build an AI medical workflow that handles patient triage, scheduling, and emergency routing using visual nodes.
+slug: examples/clinic-triage-scheduling
+description: Build a voice AI clinic workflow with medical triage protocols, appointment booking, and emergency routing using Vapi's visual workflow builder.
+---
+
+## Overview
+
+Build an AI-powered clinic receptionist workflow that handles patient triage, appointment scheduling, and emergency routing using visual nodes with medical protocol compliance and safety monitoring.
+
+**What You'll Build:**
+* Medical triage assessment with symptom-based routing
+* Emergency detection with global safety protocols
+* Provider scheduling with urgency prioritization
+* Prescription refill processing with safety checks
+
+## Prerequisites
+
+* A [Vapi account](https://dashboard.vapi.ai/).
+* Medical triage protocols and guidelines.
+* Healthcare provider scheduling system.
+
+## Scenario
+
+We will be creating a triage and scheduling workflow for Riverside Family Clinic, a primary care practice that wants to improve patient access while ensuring appropriate care routing and emergency response through sophisticated workflow automation.
+
+---
+
+## 1. Create a Knowledge Base
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ In your Vapi dashboard, click `Files` in the left sidebar.
+
+
+ - Click `Choose file`. Upload all four CSV files: `patients.csv`, `providers.csv`, `triage_protocols.csv`, and `appointments.csv`.
+ - Note the file IDs. We'll need them later to create tools.
+
+
+
+
+
+---
+
+## 2. Create Required Tools
+
+Before building the workflow, create the necessary tools in your dashboard:
+
+
+
+ In your Vapi dashboard, click **Tools** in the left sidebar.
+
+
+ Click **Create Tool** and configure:
+ - **Tool Name**: "Patient Lookup"
+ - **Tool Type**: "Function"
+ - **Function Name**: `lookup_patient`
+ - **Description**: "Look up patient record by ID"
+ - **Parameters**:
+ - `patient_id` (string, required): Patient's ID number
+ - **Server URL**: `https://jsonplaceholder.typicode.com/users`
+
+
+ This example uses JSONPlaceholder for demonstration. In production, replace with your EHR system API (Epic, Cerner, etc.).
+
+
+
+ Create another tool:
+ - **Tool Name**: "Triage Assessment"
+ - **Function Name**: `conduct_triage`
+ - **Description**: "Assess patient symptoms and determine urgency level"
+ - **Parameters**:
+ - `symptoms` (string): Description of patient symptoms
+ - `onset` (string): When symptoms started
+ - `severity` (string): Severity level (1-10)
+ - **Server URL**: `https://jsonplaceholder.typicode.com/posts`
+
+
+ This example uses JSONPlaceholder for demonstration. Replace with your medical triage system in production.
+
+
+
+ Create a third tool:
+ - **Tool Name**: "Schedule Appointment"
+ - **Function Name**: `schedule_appointment`
+ - **Description**: "Schedule patient appointments based on availability"
+ - **Parameters**:
+ - `patient_id` (string): Patient identifier
+ - `appointment_type` (string): Type of appointment needed
+ - `urgency_level` (string): Urgency classification
+ - **Server URL**: `https://jsonplaceholder.typicode.com/posts`
+
+
+ This example uses JSONPlaceholder for demonstration. In production, integrate with your appointment scheduling system.
+
+
+
+
+---
+
+## 3. Create a Workflow
+
+
+
+ Go to [dashboard.vapi.ai](https://dashboard.vapi.ai) and log in to your account.
+
+
+ Click `Workflows` in the left sidebar.
+
+
+ - Click `Create Workflow`.
+ - Enter workflow name: `Clinic Triage & Scheduling Workflow`.
+ - Select the default template (includes Call Start node).
+ - Click "Create Workflow".
+
+
+
+
+
+---
+
+## 4. Build the Workflow
+
+You'll start with a default template that includes a "Call Start" node. We'll modify the existing nodes and add new ones to create our medical triage and scheduling workflow.
+
+
+
+ The default template includes a conversation node. Click on it and configure:
+
+ **First Message**:
+ ```txt
+ Hello, you've reached Riverside Family Clinic. This is Nurse Kelly, your medical assistant. I can help you schedule appointments, assess your symptoms, or direct you to appropriate care. How may I assist you today?
+ ```
+
+ **Prompt**:
+ ```txt
+ You are Nurse Kelly, a licensed medical assistant for Riverside Family Clinic.
+
+ Listen to the patient's response and determine their primary need:
+ - "symptoms" for medical concerns or illness
+ - "appointment" for routine scheduling
+ - "prescription" for medication refills
+ - "emergency" for urgent medical situations
+ - "general" for other inquiries
+
+ Keep responses professional and under 30 words.
+ ```
+
+ **Extract Variables**:
+ - Variable: `call_purpose`
+ - Type: `String`
+ - Description: `The patient's primary need`
+ - Enum Values: `symptoms`, `appointment`, `prescription`, `emergency`, `general`
+
+
+
+ Add a **Conversation** node:
+
+ **Node Name**: `patient_identification`
+
+ **Prompt**:
+ ```txt
+ I'll need to verify your information first. Can you please provide your full name and phone number so I can look up your patient record?
+
+ If this is for someone else, please let me know your relationship to the patient.
+ ```
+
+ **Variable Extraction**:
+ - Variable: `patient_name`
+ - Type: `string`
+ - Description: `Patient's full name`
+ - Required: `true`
+ - Variable: `phone_number`
+ - Type: `string`
+ - Description: `Patient's phone number`
+ - Required: `true`
+ - Variable: `caller_relationship`
+ - Type: `string`
+ - Description: `Relationship to patient if calling for someone else`
+ - Required: `false`
+
+
+
+ Add a **Tool** node:
+
+ **Tool**: Select your pre-configured "Patient Lookup" tool from the dropdown. This tool should be created in the **Tools** section of your dashboard with:
+ - **Function Name**: `lookup_patient`
+ - **Description**: "Look up patient record by ID"
+ - **Parameters**:
+ - `patient_id` (string, required): Patient's ID number
+ - **Server URL**: `https://jsonplaceholder.typicode.com/users`
+
+
+
+ Create branching paths based on the patient's needs. Add multiple conversation nodes:
+
+ **Medical Triage Node**:
+ - **Node Name**: `medical_triage_assessment`
+ - **Prompt**: `I understand you're having some medical concerns. Let me ask you some questions to better assess your situation. What symptoms are you experiencing, and when did they start?`
+
+ **Routine Appointment Node**:
+ - **Node Name**: `routine_appointment_scheduling`
+ - **Prompt**: `I can help you schedule an appointment. What type of visit do you need - routine check-up, follow-up, or something specific?`
+
+ **Prescription Refill Node**:
+ - **Node Name**: `prescription_refill_request`
+ - **Prompt**: `I can help with your prescription refill. Which medication do you need refilled, and what's the name of the prescribing provider?`
+
+ **Emergency Assessment Node**:
+ - **Node Name**: `emergency_assessment`
+ - **Prompt**: `I understand this may be urgent. Can you describe what's happening right now? Are you experiencing any chest pain, difficulty breathing, or severe bleeding?`
+
+
+
+ Connect the nodes with conditions for the LLM to interpret:
+
+ **From greeting_and_purpose to medical_triage_assessment**:
+ - Condition: `{{ call_purpose == "symptoms" }}`
+
+ **From greeting_and_purpose to routine_appointment_scheduling**:
+ - Condition: `{{ call_purpose == "appointment" }}`
+
+ **From greeting_and_purpose to prescription_refill_request**:
+ - Condition: `{{ call_purpose == "prescription" }}`
+
+ **From greeting_and_purpose to emergency_assessment**:
+ - Condition: `{{ call_purpose == "emergency" }}`
+
+
+
+ Create a global node that monitors for emergency keywords throughout the call:
+
+ **Node Name**: `emergency_detector`
+ **Global Node**: `enabled = true`
+ **Enter Condition**: `{{ emergency_keywords_detected == true or red_flag_symptoms == true }}`
+
+ **Prompt**:
+ ```txt
+ I'm hearing some concerning symptoms. For your safety, I need to direct you to immediate medical care. Please call 911 or go to your nearest emergency room right away. Do not drive yourself - have someone else drive you or call an ambulance.
+ ```
+
+ This global node will activate whenever emergency keywords are detected, regardless of where they are in the workflow.
+
+
+
+ For the medical triage path, add these nodes:
+
+ **Symptom Collection Node**:
+ - **Node Name**: `collect_symptoms`
+ - Extract detailed symptom information, onset, severity
+
+ **Triage Protocol Tool Node**:
+ - Add a **Tool** node that calls triage protocol API with symptom data
+
+ **Urgency Classification Node**:
+ - **Node Name**: `classify_urgency`
+ - Determine urgency level: emergency, urgent, semi-urgent, routine
+ - Route to appropriate care level
+
+
+
+ **Provider Lookup Tool Node**:
+ - Add a **Tool** node that checks available appointments based on urgency and specialty
+
+ **Appointment Options Node**:
+ - **Node Name**: `present_appointment_options`
+ - Present available time slots to patient
+ - Use conditional logic based on urgency level
+
+ **Appointment Confirmation Node**:
+ - **Node Name**: `confirm_appointment`
+ - Confirm appointment details and provide instructions
+
+
+
+ **911 Routing Node**:
+ - **Node Type**: `Transfer`
+ - **Destination**: `911`
+ - Use for life-threatening emergencies
+
+ **Urgent Care Transfer Node**:
+ - **Node Type**: `Transfer`
+ - **Destination**: `+1-555-URGENT-1` (urgent care line)
+
+ **Nurse Line Transfer Node**:
+ - **Node Type**: `Transfer`
+ - **Destination**: `+1-555-NURSE-1` (triage nurse line)
+
+ **End Call Node**:
+ - **Node Type**: `Hangup`
+ - Use when patient needs are resolved
+
+
+
+---
+
+## 5. Configure Phone Number
+
+
+
+ Click `Phone Numbers` in the left sidebar of your dashboard.
+
+
+ - Click `Create Phone Number` for a new Vapi number, or
+ - Click `Import Phone Number` to use your existing clinic number
+
+
+ **Workflow**: Select your `Clinic Triage & Scheduling Workflow`
+
+ **Medical Configuration**:
+ - Enable call recording for medical documentation
+ - Set maximum call duration (e.g., 20 minutes for complex cases)
+ - Configure voicemail for after-hours calls
+ - Enable emergency transfer capabilities
+
+
+ Test the workflow with various medical scenarios:
+ - Routine appointment requests
+ - Urgent symptom assessments
+ - Emergency situations (test routing only)
+ - Prescription refill requests
+ - After-hours calls
+
+
+
+## Integrating with Real Systems
+
+This example uses JSONPlaceholder for demonstration purposes. To integrate with your actual healthcare systems:
+
+### EHR System Integration
+- **Epic**: Use [Epic on FHIR](https://fhir.epic.com/) APIs for patient data
+- **Cerner**: Use [Cerner SMART on FHIR](https://fhir.cerner.com/) APIs
+- **Allscripts**: Use [Allscripts Developer Program](https://developer.allscripts.com/) APIs
+
+### Appointment Scheduling
+- **Epic MyChart**: [Epic APIs](https://fhir.epic.com/Documentation?docId=scheduling)
+- **Cerner PowerChart**: [Cerner Scheduling APIs](https://fhir.cerner.com/millennium/r4/scheduling/)
+- **athenahealth**: [athenaCollector API](https://docs.athenahealth.com/api/)
+
+### Medical Decision Support
+- **IBM Watson Health**: [Watson for Oncology](https://www.ibm.com/watson-health)
+- **Microsoft Healthcare Bot**: [Healthcare Bot Service](https://docs.microsoft.com/en-us/healthbot/)
+- **Infermedica**: [Symptom Checker API](https://developer.infermedica.com/)
+
+
+**HIPAA Compliance**: When integrating with real healthcare systems, ensure all integrations comply with HIPAA regulations and your organization's privacy policies.
+
+
+## Next Steps
+
+Just like that, you've built a medical triage and scheduling workflow that can handle patient calls, assess symptoms, and route to appropriate care levels with 24/7 availability.
+
+Consider reading the following guides to further enhance your workflow:
+
+* [**Custom Tools**](/tools/custom-tools) - Create custom tools for EHR integration and medical protocols.
+* [**Custom Voices**](/customization/custom-voices/custom-voice) - Customize your assistant's voice for medical professionalism.
+* [**HIPAA Compliance**](/security-and-privacy/hipaa) - Ensure your medical workflows meet HIPAA requirements.
diff --git a/fern/examples/ecommerce-order-management.mdx b/fern/examples/ecommerce-order-management.mdx
new file mode 100644
index 00000000..eb5aedd5
--- /dev/null
+++ b/fern/examples/ecommerce-order-management.mdx
@@ -0,0 +1,363 @@
+---
+title: E-commerce order management workflow
+subtitle: Build an AI customer service workflow that handles orders, returns, and support using visual nodes.
+slug: examples/ecommerce-order-management
+description: Build a voice AI e-commerce workflow with order tracking, return processing, and customer support automation using Vapi's visual workflow builder.
+---
+
+## Overview
+
+Build an AI-powered e-commerce customer service workflow that handles order inquiries, returns, and customer support using visual nodes with tier-based routing and global monitoring for comprehensive automation.
+
+**What You'll Build:**
+* Order tracking with real-time status updates
+* Return processing with automated eligibility verification
+* Customer tier routing (VIP, Premium, Standard)
+* Global fraud detection and sentiment monitoring
+
+## Prerequisites
+
+* A [Vapi account](https://dashboard.vapi.ai/).
+* E-commerce platform or order management system.
+* Shipping carrier integrations.
+
+## Scenario
+
+We will be creating an order management workflow for TechGear Online, an electronics retailer that wants to automate customer service calls and improve order resolution times through sophisticated workflow automation.
+
+---
+
+## 1. Create a Knowledge Base
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ In your Vapi dashboard, click `Files` in the left sidebar.
+
+
+ - Click `Choose file`. Upload all four CSV files: `customers.csv`, `orders.csv`, `products.csv`, and `returns.csv`.
+ - Note the file IDs. We'll need them later to create tools.
+
+
+
+
+
+---
+
+## 2. Create Required Tools
+
+Before building the workflow, create the necessary tools in your dashboard:
+
+
+
+ In your Vapi dashboard, click **Tools** in the left sidebar.
+
+
+ Click **Create Tool** and configure:
+ - **Tool Name**: "Customer Lookup"
+ - **Tool Type**: "Function"
+ - **Function Name**: `lookup_customer`
+ - **Description**: "Look up customer account and order history"
+ - **Parameters**:
+ - `customer_id` (string): Customer ID to lookup
+ - **Server URL**: `https://jsonplaceholder.typicode.com/users`
+
+
+ This example uses JSONPlaceholder, a free testing API. In production, replace with your actual e-commerce API endpoint.
+
+
+
+ Create another tool:
+ - **Tool Name**: "Order Tracking"
+ - **Function Name**: `track_order`
+ - **Description**: "Track order status and shipping information"
+ - **Parameters**:
+ - `order_id` (string): Order ID to track
+ - **Server URL**: `https://jsonplaceholder.typicode.com/posts`
+
+
+ This example uses JSONPlaceholder for demonstration. Replace with your shipping provider's API (FedEx, UPS, etc.) in production.
+
+
+
+ Create a third tool:
+ - **Tool Name**: "Return Processing"
+ - **Function Name**: `process_return`
+ - **Description**: "Process return requests and generate return labels"
+ - **Parameters**:
+ - `order_id` (string): Original order ID
+ - `return_reason` (string): Reason for return
+ - **Server URL**: `https://jsonplaceholder.typicode.com/posts`
+
+
+ This example uses JSONPlaceholder for demonstration. In production, integrate with your returns management system.
+
+
+
+
+---
+
+## 3. Create a Workflow
+
+
+
+ Go to [dashboard.vapi.ai](https://dashboard.vapi.ai) and log in to your account.
+
+
+ Click `Workflows` in the left sidebar.
+
+
+ - Click `Create Workflow`.
+ - Enter workflow name: `TechGear E-commerce Support Workflow`.
+ - Select the default template (includes Call Start node).
+ - Click "Create Workflow".
+
+
+
+
+
+---
+
+## 4. Build the Workflow
+
+You'll start with a default template that includes a "Call Start" node. We'll modify the existing nodes and add new ones to create our e-commerce customer service workflow.
+
+
+
+ The default template includes a conversation node. Click on it and configure:
+
+ **Node Name**: `greeting_and_inquiry_type`
+
+ **Prompt**:
+ ```txt
+ You are Emma, the friendly customer service representative for TechGear Online.
+
+ Start with: "Hello! Thank you for calling TechGear Online customer service. This is Emma, your virtual assistant. I can help you track orders, process returns, answer product questions, or resolve any issues. How can I assist you today?"
+
+ Listen to the customer's response and determine their inquiry type:
+ - "order_tracking" for checking order status or shipping
+ - "return_exchange" for returns, exchanges, or refunds
+ - "product_inquiry" for product questions or recommendations
+ - "billing_payment" for payment or billing issues
+ - "complaint" for problems or complaints
+ - "general" for other inquiries
+
+ Keep responses friendly and under 35 words.
+ ```
+
+ **Extract Variables**:
+ - Variable: `inquiry_type`
+ - Type: `String`
+ - Description: `The customer's inquiry type`
+ - Enum Values: `order_tracking`, `return_exchange`, `product_inquiry`, `billing_payment`, `complaint`, `general`
+
+
+
+ Add a **Conversation** node:
+
+ **Node Name**: `customer_identification`
+
+ **Prompt**:
+ ```txt
+ I'll be happy to help you with that. To look up your account, can you please provide your phone number or email address associated with your TechGear Online account?
+
+ If you don't have an account, that's okay - I can still help you with general product questions.
+ ```
+
+ **Variable Extraction**:
+ - Variable: `customer_phone`
+ - Type: `string`
+ - Description: `Customer's phone number`
+ - Required: `false`
+ - Variable: `customer_email`
+ - Type: `string`
+ - Description: `Customer's email address`
+ - Required: `false`
+
+
+
+ Add a **Tool** node:
+
+ **Tool**: Select your pre-configured "Customer Lookup" tool from the dropdown. This tool should be created in the **Tools** section of your dashboard with:
+ - **Function Name**: `lookup_customer`
+ - **Description**: "Look up customer account and order history"
+ - **Parameters**:
+ - `customer_id` (string): Customer ID to lookup
+ - **Server URL**: `https://jsonplaceholder.typicode.com/users`
+
+
+
+ Create branching paths based on the customer's inquiry type. Add multiple conversation nodes:
+
+ **Order Tracking Node**:
+ - **Node Name**: `order_tracking_flow`
+ - **Prompt**: `I can help you track your order. Do you have your order number, or would you like me to look up your recent orders?`
+
+ **Return/Exchange Node**:
+ - **Node Name**: `return_exchange_flow`
+ - **Prompt**: `I can help you with returns and exchanges. Can you tell me which item you'd like to return and the reason for the return?`
+
+ **Product Inquiry Node**:
+ - **Node Name**: `product_inquiry_flow`
+ - **Prompt**: `I'd be happy to help with product information. What specific product are you interested in, or what type of device are you looking for?`
+
+ **Billing/Payment Node**:
+ - **Node Name**: `billing_payment_flow`
+ - **Prompt**: `I can help with billing and payment questions. Are you looking to update payment information, dispute a charge, or have questions about a specific order?`
+
+ **Complaint Resolution Node**:
+ - **Node Name**: `complaint_resolution_flow`
+ - **Prompt**: `I'm sorry to hear you're having an issue. I want to make this right for you. Can you tell me what happened so I can help resolve this?`
+
+
+
+ Connect the nodes with conditions for the LLM to interpret:
+
+ **From greeting_and_inquiry_type to order_tracking_flow**:
+ - Condition: `{{ inquiry_type == "order_tracking" }}`
+
+ **From greeting_and_inquiry_type to return_exchange_flow**:
+ - Condition: `{{ inquiry_type == "return_exchange" }}`
+
+ **From greeting_and_inquiry_type to product_inquiry_flow**:
+ - Condition: `{{ inquiry_type == "product_inquiry" }}`
+
+ **From greeting_and_inquiry_type to billing_payment_flow**:
+ - Condition: `{{ inquiry_type == "billing_payment" }}`
+
+ **From greeting_and_inquiry_type to complaint_resolution_flow**:
+ - Condition: `{{ inquiry_type == "complaint" }}`
+
+
+
+ Create a global node that provides special handling for VIP customers:
+
+ **Node Name**: `vip_customer_handler`
+ **Global Node**: `enabled = true`
+ **Enter Condition**: `{{ customer_tier == "VIP" or total_orders > 50 or lifetime_value > 5000 }}`
+
+ **Prompt**:
+ ```txt
+ I see you're one of our valued VIP customers. I want to make sure you receive our highest level of service today. Let me prioritize your request and see what I can do to exceed your expectations.
+ ```
+
+ This global node will activate for high-value customers, regardless of their inquiry type.
+
+
+
+ For the order tracking path, add these nodes:
+
+ **Order Number Collection Node**:
+ - **Node Name**: `collect_order_number`
+ - Extract order number or use recent orders from customer history
+
+ **Order Status Tool Node**:
+ - Add a **Tool** node that calls your order tracking API with order information
+
+ **Shipping Information Node**:
+ - **Node Name**: `provide_shipping_info`
+ - Present tracking details, delivery estimates, and shipping updates
+
+
+
+ **Return Eligibility Check Node**:
+ - **Node Name**: `check_return_eligibility`
+ - Verify return policy compliance and item condition
+
+ **Return Authorization Tool Node**:
+ - Add a **Tool** node that creates return label and authorization number
+
+ **Refund Processing Node**:
+ - **Node Name**: `process_refund`
+ - Handle refund calculations and payment processing
+
+
+
+ **Human Agent Transfer Node**:
+ - **Node Type**: `Transfer`
+ - **Destination**: `+1-555-SUPPORT` (customer service team)
+
+ **Issue Resolution Node**:
+ - **Node Name**: `resolve_issue`
+ - Provide solutions, credits, or compensations
+
+ **End Call Node**:
+ - **Node Type**: `Hangup`
+ - Use when customer issue is resolved
+
+
+
+---
+
+## 5. Configure Phone Number
+
+
+
+ Click `Phone Numbers` in the left sidebar of your dashboard.
+
+
+ - Click `Create Phone Number` for a new Vapi number, or
+ - Click `Import Phone Number` to use your existing customer service number
+
+
+ **Workflow**: Select your `TechGear Customer Service Workflow`
+
+ **Customer Service Configuration**:
+ - Enable call recording for quality assurance
+ - Set maximum call duration (e.g., 30 minutes for complex issues)
+ - Configure voicemail for after-hours support
+ - Enable priority routing for VIP customers
+
+
+ Test the workflow with various customer scenarios:
+ - Order tracking requests
+ - Return and exchange processing
+ - Product inquiries and recommendations
+ - Billing and payment issues
+ - Complaint resolution
+
+
+
+## Integrating with Real Systems
+
+This example uses JSONPlaceholder for demonstration purposes. To integrate with your actual e-commerce systems:
+
+### E-commerce Platform Integration
+- **Shopify**: Use the [Shopify Admin API](https://shopify.dev/api/admin-rest) for customer and order data
+- **WooCommerce**: Use the [WooCommerce REST API](https://woocommerce.github.io/woocommerce-rest-api-docs/)
+- **Magento**: Use the [Magento Web API](https://devdocs.magento.com/guides/v2.4/get-started/web-api-functional-testing.html)
+
+### Shipping Provider APIs
+- **FedEx**: [FedEx Web Services](https://www.fedex.com/en-us/developer/web-services.html)
+- **UPS**: [UPS Developer Kit](https://www.ups.com/upsdeveloperkit)
+- **USPS**: [USPS Web Tools](https://www.usps.com/business/web-tools-apis/)
+
+### Payment Processing
+- **Stripe**: [Stripe API](https://stripe.com/docs/api)
+- **PayPal**: [PayPal Developer](https://developer.paypal.com/)
+- **Square**: [Square API](https://developer.squareup.com/)
+
+## Next Steps
+
+Just like that, you've built an e-commerce customer service workflow that can handle order inquiries, returns, and support requests with 24/7 availability for your online store.
+
+Consider reading the following guides to further enhance your workflow:
+
+* [**Custom Tools**](/tools/custom-tools) - Create custom tools for e-commerce platform integration and order management.
+* [**Custom Voices**](/customization/custom-voices/custom-voice) - Customize your assistant's voice for customer service excellence.
+* [**Call Recording**](/assistants/call-recording) - Record calls for quality assurance and training purposes.
diff --git a/fern/examples/inbound-support.mdx b/fern/examples/inbound-support.mdx
index 2264655e..df3a751e 100644
--- a/fern/examples/inbound-support.mdx
+++ b/fern/examples/inbound-support.mdx
@@ -51,7 +51,7 @@ We will be creating a customer support agent for VapiBank, a bank that wants to
-
+
---
diff --git a/fern/examples/outbound-sales.mdx b/fern/examples/outbound-sales.mdx
index c0e86060..761af616 100644
--- a/fern/examples/outbound-sales.mdx
+++ b/fern/examples/outbound-sales.mdx
@@ -1,158 +1,353 @@
---
-title: Outbound Sales Example 📞
-subtitle: Let's build an outbound sales agent that can schedule appointments.
+title: Outbound sales workflow
+subtitle: Build an AI sales workflow that qualifies leads and schedules appointments using visual nodes.
slug: examples/outbound-sales
+description: Build a voice AI outbound sales workflow with lead qualification, CRM integration, and automated follow-up using Vapi's visual workflow builder.
---
+## Overview
-We want this agent to be able to call a list of leads and schedule appointments. We'll create our assistant, create a phone number for it, then we'll configure our server for function calling to book the appointments.
+Build an AI-powered outbound sales workflow that qualifies leads, handles objections, and schedules appointments using visual nodes with sophisticated branching logic and CRM integration.
+
+**What You'll Build:**
+* Lead qualification with BANT scoring and conditional routing
+* Objection handling with global nodes and sentiment analysis
+* Appointment scheduling with calendar integration
+* CRM updates with automated follow-up sequences
+
+## Prerequisites
+
+* A [Vapi account](https://dashboard.vapi.ai/).
+* A CRM system or customer database.
+* A calendar system for appointment scheduling.
+
+## Scenario
+
+We will be creating an outbound sales workflow for TechFlow Solutions, a B2B software company that wants to automate their lead qualification process with sophisticated branching logic to handle different prospect scenarios and increase appointment booking rates.
+
+---
+
+## 1. Create a Knowledge Base
-
- We'll start by taking a look at the [Assistant API
- reference](/api-reference/assistants/create-assistant) and define our
- assistant:
-
- ```json
- {
- "transcriber":{
- "provider": "deepgram",
- "keywords": ["Bicky:1"]
- },
- "model": {
- "provider": "openai",
- "model": "gpt-4",
- "messages": [
- {
- "role": "system",
- "content": "You're a sales agent for a Bicky Realty. You're calling a list of leads to schedule appointments to show them houses..."
- }
- ],
- "tools": [
- {
- "name": "bookAppointment",
- "description": "Used to book the appointment.",
- "parameters": {
- "type": "object",
- "properties": {
- "datetime": {
- "type": "string",
- "description": "The date and time of the appointment in ISO format."
- }
- }
- }
- }
- {
- "type": "transferCall",
- "destinations": [
- {
- "type": "number",
- "number": "+16054440129",
- "message": "I am forwarding your call. Please stay on the line."
- }
- ]
- }
- ]
- },
- "voice": {
- "provider": "openai",
- "voiceId": "onyx"
- },
- "voicemailMessage": "Hi, this is Jennifer from Bicky Realty. We were just calling to let you know...",
- "firstMessage": "Hi, this Jennifer from Bicky Realty. We're calling to schedule an appointment to show you a house. When would be a good time for you?",
- "endCallMessage": "Thanks for your time.",
- "endCallFunctionEnabled": true,
- "recordingEnabled": false,
- }
- ```
- Let's break this down:
- - `transcriber` - We're defining this to make sure the transcriber picks up the custom word "Bicky"
- - `model` - We're using the OpenAI GPT-4 model, which is better at function calling.
- - `messages` - We're defining the assistant's instructions for how to run the call.
- - `bookAppointment` in `model.tools` - We're providing a bookAppointment function with a datetime parameter. The assistant can call this during the conversation to book the appointment.
- - `transferCall` in `model.tools` - Since we've added this, the assistant will be provided the [transferCall](/assistants#transfer-call) function to use.
- - `voice` - We're using the Onyx voice from OpenAI.
- - `voicemailMessage` - If the call goes to voicemail, this message will be played.
- - `firstMessage` - This is the first message the assistant will say when the user picks up.
- - `endCallMessage` - This is the message the assistant will deciding to hang up.
- - `endCallFunctionEnabled` - This will give the assistant the [endCall](/assistants#end-call) function.
- - `recordingEnabled` - We've disabled recording, since we don't have the user's consent to record the call.
-
- We'll then make a POST request to the [Create Assistant](/api-reference/assistants/create-assistant) endpoint to create the assistant.
-
-
-
- We'll create a phone number for outbound calls using the [Phone Numbers API](/phone-calling#set-up-a-phone-number).
-
- ```json
- {
- "id": "c86b5177-5cd8-447f-9013-99e307a8a7bb",
- "orgId": "aa4c36ba-db21-4ce0-9c6e-99e307a8a7bb",
- "provider": "vapi",
- "number": "+11234567890",
- "createdAt": "2023-09-29T21:44:37.946Z",
- "updatedAt": "2023-12-08T00:57:24.706Z",
- }
- ```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ In your Vapi dashboard, click `Files` in the left sidebar.
+
+
+ - Click `Choose file`. Upload all three CSV files: `leads.csv`, `products.csv`, and `call_outcomes.csv`.
+ - Note the file IDs. We'll need them later to create tools.
+
+
+
+
+
+---
+
+## 2. Create Required Tools
- Great, let's take note of that `id` field- we'll need it later.
+Before building the workflow, create the necessary tools in your dashboard:
+
+
+ In your Vapi dashboard, click **Tools** in the left sidebar.
+
+
+ Click **Create Tool** and configure:
+ - **Tool Name**: "Lead Lookup"
+ - **Tool Type**: "Function"
+ - **Function Name**: `lookup_lead`
+ - **Description**: "Retrieve lead information and call history"
+ - **Parameters**:
+ - `lead_id` (string): Lead ID to lookup
+ - **Server URL**: `https://jsonplaceholder.typicode.com/users`
+
+
+ This example uses JSONPlaceholder for demonstration. In production, replace with your CRM API (Salesforce, HubSpot, etc.).
+
+
+
+ Create another tool:
+ - **Tool Name**: "Lead Scoring"
+ - **Function Name**: `score_lead`
+ - **Description**: "Score leads based on qualification responses"
+ - **Parameters**:
+ - `budget` (string): Budget information
+ - `authority` (string): Decision-making authority
+ - `need` (string): Business need assessment
+ - `timeline` (string): Purchase timeline
+ - **Server URL**: `https://jsonplaceholder.typicode.com/posts`
+
+
+ This example uses JSONPlaceholder for demonstration. Replace with your lead scoring system in production.
+
-
- When the assistant calls that `bookAppointment` function, we'll want to handle that function call and actually book the appointment. We also want to let the user know if booking the appointment was unsuccessful.
+
+ Create a third tool:
+ - **Tool Name**: "CRM Update"
+ - **Function Name**: `update_crm`
+ - **Description**: "Update CRM with call outcomes and next steps"
+ - **Parameters**:
+ - `lead_id` (string): Lead identifier
+ - `call_outcome` (string): Result of the call
+ - `next_steps` (string): Planned follow-up actions
+ - **Server URL**: `https://jsonplaceholder.typicode.com/posts`
+
+
+ This example uses JSONPlaceholder for demonstration. In production, integrate with your CRM system.
+
+
+
+
+---
- First, we'll create an endpoint on our server for Vapi to hit. It'll receive messages as shown in the [Function Calling](/server-url#function-calling) docs. Once created, we'll add that endpoint URL to the **Server URL** field in the Account page on the [Vapi Dashboard](https://dashboard.vapi.ai).
+## 3. Create a Workflow
+
+
+ Go to [dashboard.vapi.ai](https://dashboard.vapi.ai) and log in to your account.
+
+
+ Click `Workflows` in the left sidebar.
-
- So now, when the assistant decides to call `bookAppointment`, our server will get something like this:
+
+ - Click `Create Workflow`.
+ - Enter workflow name: `TechFlow Sales Qualification Workflow`.
+ - Select the default template (includes Call Start node).
+ - Click "Create Workflow".
+
+
- ```json
- {
- "message": {
- "type": "function-call",
- "call": { Call Object },
- "functionCall": {
- "name": "bookAppointment",
- "parameters": "{ \"datetime\": \"2023-09-29T21:44:37.946Z\"}"
- }
- }
- }
- ```
+
- We'll do our own logic to book the appointment, then we'll respond to the request with the result to let the assistant know it was booked:
+---
- ```json
- { "result": "The appointment was booked successfully." }
- ```
+## 4. Build the Workflow
- or, if it failed:
+You'll start with a default template that includes a "Call Start" node. We'll modify the existing nodes and add new ones to create our outbound sales workflow.
- ```json
- { "result": "The appointment time is unavailable, please try another time." }
+
+
+ The default template includes a conversation node. Click on it and configure:
+
+ **Node Name**: `opening_and_permission`
+
+ **Prompt**:
+ ```txt
+ You are Alex, a professional outbound sales representative for TechFlow Solutions.
+
+ Start with: "Hi, this is Alex calling from TechFlow Solutions. I hope I'm catching you at a good time. I'm reaching out because I noticed your company might benefit from our workflow automation platform. Do you have just 2 minutes to chat?"
+
+ Listen for their response and determine:
+ - "permission_granted" if they agree to talk
+ - "busy_reschedule" if they're busy but open to rescheduling
+ - "not_interested" if they decline
+ - "gatekeeper" if you're speaking to someone who isn't the decision maker
+
+ Keep responses under 30 words and be respectful of their time.
```
- So, when the assistant calls this function, these results will be appended to the conversation, and the assistant will respond to the user knowing the result.
+ **Extract Variables**:
+ - Variable: `permission_status`
+ - Type: `String`
+ - Description: `The prospect's response to the initial request`
+ - Enum Values: `permission_granted`, `busy_reschedule`, `not_interested`, `gatekeeper`
+
+
+
+ Add a **Tool** node that runs before the opening:
+
+ **Tool**: Select your pre-configured "Lead Lookup" tool from the dropdown. This tool should be created in the **Tools** section of your dashboard with:
+ - **Function Name**: `lookup_lead`
+ - **Description**: "Retrieve lead information and call history"
+ - **Parameters**:
+ - `lead_id` (string): Lead ID to lookup
+ - **Server URL**: `https://jsonplaceholder.typicode.com/users`
+
+
+
+ Create branching paths based on the prospect's response. Add multiple conversation nodes:
- Great, now we're ready to start calling leads!
-
+ **Discovery Questions Node**:
+ - **Node Name**: `discovery_questions`
+ - **Prompt**: `Great! I appreciate your time. To better understand how we might help, can you tell me about your current workflow challenges? Specifically, what manual processes are taking up most of your team's time?`
-
- We'll use the [Create Phone Call](/api-reference/calls/create-phone-call) endpoint to place a call to a lead:
+ **Reschedule Node**:
+ - **Node Name**: `schedule_callback`
+ - **Prompt**: `I completely understand. When would be a better time for a quick 5-minute conversation? I have availability tomorrow morning or afternoon.`
- ```json
- {
- "phoneNumberId": "c86b5177-5cd8-447f-9013-99e307a8a7bb",
- "assistantId": "d87b5177-5cd8-447f-9013-99e307a8a7bb",
- "customer": {
- "number": "+11234567890"
- }
- }
+ **Objection Handling Node**:
+ - **Node Name**: `handle_initial_objection`
+ - **Prompt**: `I understand you might not be looking for new solutions right now. Can I ask what you're currently using for workflow automation? I might have some insights that could be valuable.`
+
+ **Gatekeeper Node**:
+ - **Node Name**: `gatekeeper_routing`
+ - **Prompt**: `I appreciate you taking the call. I'm looking to speak with whoever handles software decisions or operations. Would that be you, or could you point me in the right direction?`
+
+
+
+ Connect the nodes with conditions for the LLM to interpret:
+
+ **From opening_and_permission to discovery_questions**:
+ - Condition: `{{ permission_status == "permission_granted" }}`
+
+ **From opening_and_permission to schedule_callback**:
+ - Condition: `{{ permission_status == "busy_reschedule" }}`
+
+ **From opening_and_permission to handle_initial_objection**:
+ - Condition: `{{ permission_status == "not_interested" }}`
+
+ **From opening_and_permission to gatekeeper_routing**:
+ - Condition: `{{ permission_status == "gatekeeper" }}`
+
+
+
+ Create a global node that handles objections throughout the call:
+
+ **Node Name**: `objection_handler`
+ **Global Node**: `enabled = true`
+ **Enter Condition**: `{{ objection_detected == true or negative_sentiment == true }}`
+
+ **Prompt**:
+ ```txt
+ I hear your concern, and that's completely valid. Many of our clients had similar thoughts initially. Let me address that specific point and see if we can find a solution that makes sense for your situation.
```
+
+ This global node will activate whenever an objection is detected, regardless of where they are in the sales conversation.
+
+
+
+ For prospects who engage, add these qualification nodes:
+
+ **BANT Qualification Node**:
+ - **Node Name**: `bant_qualification`
+ - Extract budget, authority, need, and timeline information
+
+ **Lead Scoring Tool Node**:
+ - Add a **Tool** node that calls lead scoring API based on qualification responses
+
+ **Qualification Results Node**:
+ - **Node Name**: `route_by_score`
+ - Route based on lead score (hot, warm, cold)
+
+
+
+ **Industry-Specific Pitch Node**:
+ - **Node Name**: `tailored_pitch`
+ - Present value proposition based on their industry and pain points
+
+ **ROI Demonstration Node**:
+ - **Node Name**: `show_roi`
+ - Provide specific ROI examples and case studies
+
+ **Demo Offer Node**:
+ - **Node Name**: `offer_demo`
+ - Propose a product demonstration meeting
+
+
+
+ **Calendar Check Tool Node**:
+ - Add a **Tool** node that checks sales team calendar for available demo slots
+
+ **Appointment Confirmation Node**:
+ - **Node Name**: `confirm_appointment`
+ - Confirm meeting details and send calendar invite
+
+ **CRM Update Tool Node**:
+ - Add a **Tool** node that records call outcome and next steps in CRM
+
- Since we also defined a `transferCall` tool, when the user asks to speak to a human, the assistant will transfer the call to that number automatically.
+
+ **Transfer to Sales Rep Node**:
+ - **Node Type**: `Transfer`
+ - **Destination**: `+1-555-SALES-1` (your sales team number)
- We can then check the [Dashboard](https://dashboard.vapi.ai) to see the call logs and read the transcripts.
+ **Schedule Follow-up Node**:
+ - **Node Name**: `schedule_followup`
+ - Set automated follow-up call for future date
+ **End Call Node**:
+ - **Node Type**: `Hangup`
+ - Use when prospect is not qualified or requests no further contact
+
+---
+
+## 5. Configure Phone Number for Outbound Calls
+
+
+
+ Click `Phone Numbers` in the left sidebar of your dashboard.
+
+
+ - Click `Create Phone Number` for a new Vapi number, or
+ - Click `Import Phone Number` to use your existing number from Twilio/Telnyx
+
+
+ **Assistant**: Select your `Alex - Sales Agent` assistant
+ **Workflow**: Ensure it's linked to your `TechFlow Sales Qualification Workflow`
+
+ **Outbound Configuration**:
+ - Enable outbound calling capabilities
+ - Set caller ID name to "TechFlow Solutions"
+ - Configure voicemail detection and handling
+ - Set maximum call duration (e.g., 10 minutes)
+
+
+ Use the Vapi API to initiate test outbound calls:
+ ```bash
+ curl -X POST https://api.vapi.ai/call \
+ -H "Authorization: Bearer YOUR_API_KEY" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "phoneNumberId": "your-phone-number-id",
+ "customer": {
+ "number": "+1234567890"
+ },
+ "assistantId": "your-assistant-id"
+ }'
+ ```
+
+
+
+## Integrating with Real Systems
+
+This example uses JSONPlaceholder for demonstration purposes. To integrate with your actual sales systems:
+
+### CRM Platform Integration
+- **Salesforce**: Use the [Salesforce REST API](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/)
+- **HubSpot**: Use the [HubSpot API](https://developers.hubspot.com/docs/api/overview)
+- **Pipedrive**: Use the [Pipedrive API](https://developers.pipedrive.com/docs/api/v1)
+
+### Calendar Integration
+- **Google Calendar**: [Google Calendar API](https://developers.google.com/calendar/api)
+- **Microsoft Outlook**: [Microsoft Graph API](https://docs.microsoft.com/en-us/graph/api/resources/calendar)
+- **Calendly**: [Calendly API](https://developer.calendly.com/)
+
+### Communication Tools
+- **Twilio**: [Twilio API](https://www.twilio.com/docs/usage/api) for SMS and voice
+- **SendGrid**: [SendGrid API](https://docs.sendgrid.com/api-reference) for email
+- **Slack**: [Slack API](https://api.slack.com/) for team notifications
+
+## Next Steps
+
+Just like that, you've built an outbound sales qualification workflow that can handle lead qualification, objection handling, and appointment scheduling with automated CRM integration.
+
+Consider reading the following guides to further enhance your workflow:
+
+* [**Custom Tools**](/tools/custom-tools) - Create custom tools for CRM integration and lead management.
+* [**Voice Formatting Plan**](/assistants/voice-formatting-plan) - Configure speech patterns for professional sales conversations.
+* [**Call Analysis**](/assistants/call-analysis) - Analyze call performance and optimize sales conversations.
diff --git a/fern/examples/pizza-website.mdx b/fern/examples/pizza-website.mdx
deleted file mode 100644
index 0f525093..00000000
--- a/fern/examples/pizza-website.mdx
+++ /dev/null
@@ -1,165 +0,0 @@
----
-title: Pizza Website Example 🍕
-subtitle: Let's build a pizza ordering assistant for our website.
-slug: examples/pizza-website
----
-
-
-In this example, we'll be using the [Web SDK](https://github.com/VapiAI/web) to create an assistant that can take a pizza order. Since all the [Client SDKs](/sdks) have equivalent functionality, you can use this example as a guide for any Vapi client.
-
-We want to add a button to the page to start a call, update our UI with the call status, and display what the user's saying while they say it. When the user mentions a topping, we should add it to the pizza. When they're done, we should redirect them to checkout.
-
-
-
- We'll start by taking a look at the [Assistant API
- reference](/api-reference/assistants/create-assistant) and define our
- assistant:
-
- ```json
- {
- "model": {
- "provider": "openai",
- "model": "gpt-4",
- "messages": [
- {
- "role": "system",
- "content": "You're a pizza ordering assistant. The user will ask for toppings, you'll add them. When they're done, you'll redirect them to checkout."
- }
- ],
- "functions": [
- {
- "name": "addTopping",
- "description": "Used to add a topping to the pizza.",
- "parameters": {
- "type": "object",
- "properties": {
- "topping": {
- "type": "string",
- "description": "The name of the topping. For example, 'pepperoni'."
- }
- }
- }
- },
- {
- "name": "goToCheckout",
- "description": "Redirects the user to checkout and order their pizza.",
- "parameters": {"type": "object", "properties": {}}
- }
- ]
- },
- "firstMessage": "Hi, I'm the pizza ordering assistant. What toppings would you like?",
- }
- ```
- Let's break this down:
- - `model` - We're using the OpenAI GPT-4 model, which is better at function calling.
- - `messages` - We're defining the assistant's instructions for how to run the call.
- - `functions` - We're providing a addTopping function with a topping parameter. The assistant can call this during the conversation to add a topping. We're also adding goToCheckout, with an empty parameters object. The assistant can call this to redirect the user to checkout.
- - `firstMessage` - This is the first message the assistant will say when the user starts the call.
-
- We'll then make a POST request to the [Create Assistant](/api-reference/assistants/create-assistant) endpoint to create the assistant.
-
-
-
- We'll follow the `README` for the [Web SDK](https://github.com/VapiAI/web) to get it installed.
-
- We'll then get our **Public Key** from the [Vapi Dashboard](https://dashboard.vapi.ai) and initialize the SDK:
-
- ```js
- import Vapi from '@vapi-ai/web';
-
- const vapi = new Vapi('your-web-token');
- ```
-
-
-
- We'll add a button to the page that starts the call when clicked:
-
- ```html
-
-
- ```
-
- ```js
- const startCallButton = document.getElementById('start-call');
-
- startCallButton.addEventListener('click', async () => {
- await vapi.start('your-assistant-id');
- });
-
- const stopCallButton = document.getElementById('stop-call');
-
- stopCallButton.addEventListener('click', async () => {
- await vapi.stop();
- });
- ```
-
-
-
- ```js
- vapi.on('call-start', () => {
- // Update UI to show that the call has started
- });
-
- vapi.on('call-end', () => {
- // Update UI to show that the call has ended
- });
- ```
-
-
-
-
- ```js
- vapi.on('speech-start', () => {
- // Update UI to show that the assistant is speaking
- });
-
-vapi.on('speech-end', () => {
-// Update UI to show that the assistant is done speaking
-});
-
-````
-
-
-
-
- All messages send to the [Server URL](/server-url), including `transcript` and `function-call` messages, are also sent to the client as `message` events. We'll need to check the `type` of the message to see what type it is.
-
-```js
-vapi.on("message", (msg) => {
- if (msg.type !== "transcript") return;
-
- if (msg.transcriptType === "partial") {
- // Update UI to show the live partial transcript
- }
-
- if (msg.transcriptType === "final") {
- // Update UI to show the final transcript
- }
-});
-````
-
-
-
-
-```javascript
-vapi.on('message', (msg) => {
- if (msg.type !== "function-call") return;
-
-if (msg.functionCall.name === "addTopping") {
-const topping = msg.functionCall.parameters.topping;
-// Add the topping to the pizza
-}
-
-if (msg.functionCall.name === "goToCheckout") {
-// Redirect the user to checkout
-}
-});
-
-```
-
-
-You should now have a working pizza ordering assistant! 🍕
-
-
-
-```
diff --git a/fern/knowledge-base/using-query-tool.mdx b/fern/knowledge-base/using-query-tool.mdx
index 5cf65c36..22747a33 100644
--- a/fern/knowledge-base/using-query-tool.mdx
+++ b/fern/knowledge-base/using-query-tool.mdx
@@ -24,7 +24,18 @@ The Query Tool is a powerful feature that allows your voice AI assistant to acce
### **Step 1: Upload Your Files**
-Before creating a query tool, you need to upload the files that will form your knowledge base. You can upload files via the API:
+Before creating a query tool, you need to upload the files that will form your knowledge base.
+
+#### Option 1: Using the Dashboard (Recommended)
+
+1. Navigate to **Files** in your Vapi dashboard
+2. Click **Upload File** or **Choose file**
+3. Select the files you want to upload from your computer
+4. Wait for the upload to complete and note the file IDs that are generated
+
+#### Option 2: Using the API
+
+Alternatively, you can upload files via the API:
```bash
curl --location 'https://api.vapi.ai/file' \
@@ -36,7 +47,23 @@ After uploading, you'll receive file IDs that you'll need for the next step.
### **Step 2: Create a Query Tool**
-Use the following API call to create a query tool that references your knowledge base files:
+Create a query tool that references your knowledge base files:
+
+#### Option 1: Using the Dashboard (Recommended)
+
+1. Navigate to **Tools** in your Vapi dashboard
+2. Click **Create Tool**
+3. Select **Query** as the tool type
+4. Configure the tool:
+ - **Tool Name**: "Product Query"
+ - **Knowledge Bases**: Add your knowledge base with:
+ - **Name**: `product-kb`
+ - **Description**: "Use this knowledge base when the user asks or queries about the product or services"
+ - **File IDs**: Select the files you uploaded in Step 1
+
+#### Option 2: Using the API
+
+Alternatively, you can create the tool via API:
```bash
curl --location 'https://api.vapi.ai/tool/' \
@@ -69,9 +96,19 @@ curl --location 'https://api.vapi.ai/tool/' \
### **Step 3: Attach the Query Tool to Your Assistant**
-After creating the query tool, you'll receive a tool ID. Use this ID to attach the tool to your assistant:
+After creating the query tool, you need to attach it to your assistant:
-#### Option 1: Using the API
+#### Option 1: Using the Dashboard (Recommended)
+
+1. Navigate to **Assistants** in your Vapi dashboard
+2. Select the assistant you want to configure
+3. Go to the **Tools** section
+4. Click **Add Tool** and select your query tool from the dropdown
+5. Save and publish your assistant
+
+#### Option 2: Using the API
+
+Alternatively, you can attach the tool via API using the tool ID:
```bash
curl --location --request PATCH 'https://api.vapi.ai/assistant/ASSISTANT_ID' \
@@ -93,14 +130,6 @@ curl --location --request PATCH 'https://api.vapi.ai/assistant/ASSISTANT_ID' \
just the toolIds field. This will overwrite any existing model configuration.
-#### Option 2: Using the Dashboard
-
-1. Navigate to the Assistant section in your Vapi dashboard
-2. Select the assistant you want to configure
-3. Go to the Tools section
-4. Add the query tool by selecting it from the available tools
-5. Save and publish your assistant
-
+
+ We'll build a customer support agent that can process inbound phone calls and assist with common banking issues.
+
+
+ We'll build an automated appointment booking system for a barbershop.
+
- We'll build a customer support agent that can process inbound phone calls and assist with common banking issues.
+ We'll build a medical triage workflow with emergency routing and appointment scheduling.
- We'll build an order taking agent for our pizza website.
+ We'll build an order management workflow for tracking, returns, and customer support.
diff --git a/fern/static/images/quickstart/vapis-pizzeria.png b/fern/static/images/quickstart/vapis-pizzeria.png
deleted file mode 100644
index 1294d954..00000000
Binary files a/fern/static/images/quickstart/vapis-pizzeria.png and /dev/null differ
diff --git a/fern/static/spreadsheets/appointment-scheduling/appointments.csv b/fern/static/spreadsheets/appointment-scheduling/appointments.csv
new file mode 100644
index 00000000..6939a1d2
--- /dev/null
+++ b/fern/static/spreadsheets/appointment-scheduling/appointments.csv
@@ -0,0 +1,6 @@
+appointment_id,customer_id,service_id,barber,date,time,status
+APT001,CUST001,SVC001,Mike,2024-01-25,10:00,Scheduled
+APT002,CUST002,SVC004,Tony,2024-01-25,14:30,Scheduled
+APT003,CUST003,SVC002,Mike,2024-01-26,09:15,Scheduled
+APT004,CUST004,SVC003,Tony,2024-01-26,11:00,Scheduled
+APT005,CUST005,SVC001,Tony,2024-01-27,15:45,Scheduled
diff --git a/fern/static/spreadsheets/appointment-scheduling/customers.csv b/fern/static/spreadsheets/appointment-scheduling/customers.csv
new file mode 100644
index 00000000..ffc4aeb6
--- /dev/null
+++ b/fern/static/spreadsheets/appointment-scheduling/customers.csv
@@ -0,0 +1,6 @@
+customer_id,name,phone,email,preferred_barber,last_visit
+CUST001,Tony Martinez,+1-555-0201,tony.m@email.com,Mike,2024-01-10
+CUST002,James Wilson,+1-555-0202,james.w@email.com,Tony,2024-01-15
+CUST003,Robert Brown,+1-555-0203,robert.b@email.com,Mike,2024-01-08
+CUST004,Michael Davis,+1-555-0204,michael.d@email.com,Any,2024-01-12
+CUST005,Christopher Lee,+1-555-0205,chris.l@email.com,Tony,2024-01-18
diff --git a/fern/static/spreadsheets/appointment-scheduling/services.csv b/fern/static/spreadsheets/appointment-scheduling/services.csv
new file mode 100644
index 00000000..165bd185
--- /dev/null
+++ b/fern/static/spreadsheets/appointment-scheduling/services.csv
@@ -0,0 +1,5 @@
+service_id,name,duration_minutes,price,description
+SVC001,Haircut,30,25.00,Classic men's haircut and styling
+SVC002,Beard Trim,15,15.00,Professional beard trimming and shaping
+SVC003,Shampoo & Style,45,35.00,Hair wash and professional styling
+SVC004,Full Grooming,60,45.00,Complete haircut and beard grooming package
diff --git a/fern/static/spreadsheets/clinic/appointments.csv b/fern/static/spreadsheets/clinic/appointments.csv
new file mode 100644
index 00000000..aab5c017
--- /dev/null
+++ b/fern/static/spreadsheets/clinic/appointments.csv
@@ -0,0 +1,6 @@
+appointment_id,patient_id,provider_id,date,time,type,status,notes
+APT001,PAT001,PROV001,2024-01-25,09:00,Routine Checkup,Scheduled,Annual physical
+APT002,PAT002,PROV002,2024-01-25,14:30,Follow-up,Scheduled,Blood pressure check
+APT003,PAT003,PROV001,2024-01-26,10:15,Sick Visit,Scheduled,Flu symptoms
+APT004,PAT004,PROV003,2024-01-26,11:00,Well Child,Scheduled,6-month checkup
+APT005,PAT005,PROV002,2024-01-27,15:45,Consultation,Scheduled,Diabetes management
diff --git a/fern/static/spreadsheets/clinic/patients.csv b/fern/static/spreadsheets/clinic/patients.csv
new file mode 100644
index 00000000..d196e8d3
--- /dev/null
+++ b/fern/static/spreadsheets/clinic/patients.csv
@@ -0,0 +1,6 @@
+patient_id,name,phone,email,date_of_birth,primary_provider,insurance
+PAT001,John Smith,+1-555-0401,john.smith@email.com,1985-03-15,Dr. Johnson,Blue Cross
+PAT002,Mary Davis,+1-555-0402,mary.davis@email.com,1978-07-22,Dr. Williams,Aetna
+PAT003,Robert Wilson,+1-555-0403,robert.w@email.com,1992-11-08,Dr. Johnson,United Health
+PAT004,Jennifer Brown,+1-555-0404,jennifer.b@email.com,1988-05-30,Dr. Martinez,Cigna
+PAT005,Michael Lee,+1-555-0405,michael.lee@email.com,1975-12-12,Dr. Williams,Medicare
diff --git a/fern/static/spreadsheets/clinic/providers.csv b/fern/static/spreadsheets/clinic/providers.csv
new file mode 100644
index 00000000..7c14163c
--- /dev/null
+++ b/fern/static/spreadsheets/clinic/providers.csv
@@ -0,0 +1,5 @@
+provider_id,name,specialty,phone,email,schedule_days,appointment_duration
+PROV001,Dr. Johnson,Family Medicine,+1-555-0501,dr.johnson@clinic.com,Mon-Fri,30
+PROV002,Dr. Williams,Internal Medicine,+1-555-0502,dr.williams@clinic.com,Tue-Sat,30
+PROV003,Dr. Martinez,Pediatrics,+1-555-0503,dr.martinez@clinic.com,Mon-Wed-Fri,20
+PROV004,Nurse Kelly,Triage Nurse,+1-555-0504,nurse.kelly@clinic.com,Mon-Sun,15
diff --git a/fern/static/spreadsheets/clinic/triage_protocols.csv b/fern/static/spreadsheets/clinic/triage_protocols.csv
new file mode 100644
index 00000000..e7f95572
--- /dev/null
+++ b/fern/static/spreadsheets/clinic/triage_protocols.csv
@@ -0,0 +1,6 @@
+protocol_id,symptom_category,urgency_level,recommended_action,time_frame
+TRIAGE001,Chest Pain,Emergency,Call 911 immediately,Immediate
+TRIAGE002,High Fever,Urgent,Same day appointment,Within 4 hours
+TRIAGE003,Routine Checkup,Routine,Schedule regular appointment,Within 2 weeks
+TRIAGE004,Medication Refill,Low,Pharmacy or nurse consultation,Within 24 hours
+TRIAGE005,Minor Injury,Semi-urgent,Urgent care or next day appointment,Within 24 hours
diff --git a/fern/static/spreadsheets/ecommerce/customers.csv b/fern/static/spreadsheets/ecommerce/customers.csv
new file mode 100644
index 00000000..ad093ad0
--- /dev/null
+++ b/fern/static/spreadsheets/ecommerce/customers.csv
@@ -0,0 +1,6 @@
+customer_id,name,email,phone,tier,total_orders,lifetime_value
+CUST001,John Smith,john.smith@email.com,+1-555-0101,Premium,15,2500.00
+CUST002,Sarah Johnson,sarah.j@email.com,+1-555-0102,VIP,45,8750.00
+CUST003,Mike Davis,mike.davis@email.com,+1-555-0103,Standard,3,150.00
+CUST004,Emily Brown,emily.brown@email.com,+1-555-0104,Premium,22,3200.00
+CUST005,David Wilson,david.w@email.com,+1-555-0105,VIP,67,12500.00
diff --git a/fern/static/spreadsheets/ecommerce/orders.csv b/fern/static/spreadsheets/ecommerce/orders.csv
new file mode 100644
index 00000000..17642c39
--- /dev/null
+++ b/fern/static/spreadsheets/ecommerce/orders.csv
@@ -0,0 +1,6 @@
+order_id,customer_id,product_name,status,order_date,total_amount,tracking_number
+ORD001,CUST001,Wireless Headphones,Shipped,2024-01-15,199.99,1Z999AA1234567890
+ORD002,CUST002,Gaming Laptop,Delivered,2024-01-10,1299.99,1Z999AA1234567891
+ORD003,CUST003,Phone Case,Processing,2024-01-20,29.99,
+ORD004,CUST001,Bluetooth Speaker,Delivered,2024-01-05,89.99,1Z999AA1234567892
+ORD005,CUST004,Tablet Stand,Shipped,2024-01-18,45.99,1Z999AA1234567893
diff --git a/fern/static/spreadsheets/ecommerce/products.csv b/fern/static/spreadsheets/ecommerce/products.csv
new file mode 100644
index 00000000..407e259a
--- /dev/null
+++ b/fern/static/spreadsheets/ecommerce/products.csv
@@ -0,0 +1,6 @@
+product_id,name,category,price,stock_quantity,description
+PROD001,Wireless Headphones,Audio,199.99,50,Premium noise-canceling wireless headphones
+PROD002,Gaming Laptop,Computers,1299.99,15,High-performance gaming laptop with RTX graphics
+PROD003,Phone Case,Accessories,29.99,200,Protective case for smartphones
+PROD004,Bluetooth Speaker,Audio,89.99,75,Portable Bluetooth speaker with bass boost
+PROD005,Tablet Stand,Accessories,45.99,100,Adjustable tablet and phone stand
diff --git a/fern/static/spreadsheets/ecommerce/returns.csv b/fern/static/spreadsheets/ecommerce/returns.csv
new file mode 100644
index 00000000..200734a0
--- /dev/null
+++ b/fern/static/spreadsheets/ecommerce/returns.csv
@@ -0,0 +1,4 @@
+return_id,order_id,customer_id,reason,status,return_date,refund_amount
+RET001,ORD002,CUST002,Defective item,Approved,2024-01-12,1299.99
+RET002,ORD001,CUST001,Wrong size,Processing,2024-01-16,199.99
+RET003,ORD004,CUST001,Not as described,Completed,2024-01-08,89.99
diff --git a/fern/static/spreadsheets/outbound-sales/call_outcomes.csv b/fern/static/spreadsheets/outbound-sales/call_outcomes.csv
new file mode 100644
index 00000000..57e11ff0
--- /dev/null
+++ b/fern/static/spreadsheets/outbound-sales/call_outcomes.csv
@@ -0,0 +1,6 @@
+call_id,lead_id,call_date,outcome,next_action,notes
+CALL001,LEAD001,2024-01-15,Demo Scheduled,Follow-up call,Interested in Pro version for team of 75
+CALL002,LEAD002,2024-01-16,Not Interested,No follow-up,Already using competitor solution
+CALL003,LEAD003,2024-01-17,Callback Requested,Call back in 1 week,Decision maker unavailable
+CALL004,LEAD004,2024-01-18,Qualified Lead,Send proposal,Budget confirmed for Basic plan
+CALL005,LEAD005,2024-01-19,Demo Scheduled,Product demo next week,Enterprise requirements discussion
diff --git a/fern/static/spreadsheets/outbound-sales/leads.csv b/fern/static/spreadsheets/outbound-sales/leads.csv
new file mode 100644
index 00000000..c2a57cf7
--- /dev/null
+++ b/fern/static/spreadsheets/outbound-sales/leads.csv
@@ -0,0 +1,6 @@
+lead_id,company,contact_name,phone,email,industry,company_size,lead_score
+LEAD001,TechCorp Inc,Sarah Johnson,+1-555-0301,sarah@techcorp.com,Technology,50-100,85
+LEAD002,Marketing Plus,Mike Davis,+1-555-0302,mike@marketingplus.com,Marketing,10-25,72
+LEAD003,Global Solutions,Emily Brown,+1-555-0303,emily@globalsol.com,Consulting,100-500,91
+LEAD004,StartupXYZ,David Wilson,+1-555-0304,david@startupxyz.com,Technology,1-10,68
+LEAD005,Enterprise Corp,Lisa Anderson,+1-555-0305,lisa@enterprise.com,Finance,500+,95
diff --git a/fern/static/spreadsheets/outbound-sales/products.csv b/fern/static/spreadsheets/outbound-sales/products.csv
new file mode 100644
index 00000000..caf2718e
--- /dev/null
+++ b/fern/static/spreadsheets/outbound-sales/products.csv
@@ -0,0 +1,6 @@
+product_id,name,category,price_monthly,description,target_company_size
+PROD001,TechFlow Basic,Workflow Automation,99.00,Basic workflow automation for small teams,1-25
+PROD002,TechFlow Pro,Workflow Automation,299.00,Advanced automation with integrations,25-100
+PROD003,TechFlow Enterprise,Workflow Automation,999.00,Enterprise-grade automation platform,100+
+PROD004,Analytics Add-on,Analytics,149.00,Advanced analytics and reporting module,Any
+PROD005,API Integration,Integration,199.00,Custom API integration services,Any
diff --git a/fern/static/videos/create-workflow.mp4 b/fern/static/videos/create-workflow.mp4
new file mode 100644
index 00000000..244078f8
Binary files /dev/null and b/fern/static/videos/create-workflow.mp4 differ
diff --git a/fern/static/videos/upload-files.mp4 b/fern/static/videos/upload-files.mp4
new file mode 100644
index 00000000..bf1d43dd
Binary files /dev/null and b/fern/static/videos/upload-files.mp4 differ
diff --git a/fern/tools/custom-tools.mdx b/fern/tools/custom-tools.mdx
index f0d4b73c..a6ed838f 100644
--- a/fern/tools/custom-tools.mdx
+++ b/fern/tools/custom-tools.mdx
@@ -4,93 +4,132 @@ subtitle: Learn how to create and configure Custom Tools for use by your Vapi as
slug: tools/custom-tools
---
+This guide shows you how to create custom tools for your Vapi assistants. We recommend using the Vapi dashboard's dedicated Tools section, which provides a visual interface for creating and managing tools that can be reused across multiple assistants. For advanced users, API configuration is also available.
-This guide focuses on configuring tools within your Vapi assistant using the provided sample payload as a reference. We'll explore how to adapt the existing structure to fit your specific needs and desired functionalities.
+## Creating Tools in the Dashboard (Recommended)
-## Understanding the Tool Structure
+### Step 1: Navigate to the Tools Section
-The sample payload demonstrates the configuration for a "function" type tool. Let's break down its key components:
+1. Open your [Vapi Dashboard](https://dashboard.vapi.ai)
+2. Click **Tools** in the left sidebar
+3. Click **Create Tool** to start building your custom tool
-```json
-{
- "type": "function",
- "messages": [ ... ],
- "function": { ... },
- "async": false,
- "server": { ... }
-}
-```
-1. **type:** This remains as "function" if you're setting up an API call.
-2. **messages:** This array holds the messages the AI will communicate to the user at different stages of the tool's execution.
-3. **function:** Defines the function details:
- - **name:** The unique identifier for your function.
- - **parameters:** (Optional) An object describing the parameters expected by the function.
- - **description:** (Optional) A description of the function's purpose.
-4. **async:** Set to "true" if the function call should be asynchronous, allowing the AI to continue without waiting for the response. Use "false" for synchronous calls.
-5. **server:** Provides the URL of the server where the function is hosted.
-
-## Adapting the Payload for Your Needs
-
-1. **Modify Function Details:**
- - Change the "name" to reflect your specific function.
- - Adjust the "parameters" object according to the data your function requires.
- - Update the "description" to accurately explain the function's purpose.
-2. **Customize Messages:**
- - Edit the content of each message within the "messages" array to align with your desired communication style and information.
- - Add or remove messages as needed. You can include messages like "request-start", "request-response-delayed", "request-complete", and "request-failed" to inform the user about the tool's progress.
-3. **Set Server URL:**
- - Replace the existing URL in the "server" object with the endpoint of your server hosting the function.
-4. **Choose Asynchronous Behavior (Optional):**
- - Change "async" to "true" if you want the AI to continue without waiting for the function's response.
-
-### Example Modification
-
-Let's say you want to create a tool that fetches the weather for a given location. You would modify the payload as follows:
+### Step 2: Configure Your Tool
-```json
-{
+The dashboard provides a user-friendly interface to configure your tool:
+
+1. **Tool Type**: Select "Function" for custom API integrations
+2. **Tool Name**: Give your tool a descriptive name (e.g., "Weather Lookup")
+3. **Description**: Explain what your tool does
+4. **Tool Configuration**:
+ - **Tool Name**: The identifier for your function (e.g., `get_weather`)
+ - **Parameters**: Define the input parameters your function expects
+ - **Server URL**: The endpoint where your function is hosted
+
+### Step 3: Configure Messages
+
+Set up the messages your assistant will speak during tool execution. For example, if you want custom messages you can add something like this:
+
+- **Request Start**: "Checking the weather forecast. Please wait..."
+- **Request Complete**: "The weather information has been retrieved."
+- **Request Failed**: "I couldn't get the weather information right now."
+- **Request Delayed**: "There's a slight delay with the weather service."
+
+### Step 4: Advanced Settings
+
+Configure additional options:
+- **Async Mode**: Enable if the tool should run asynchronously
+- **Timeout Settings**: Set how long to wait for responses
+- **Error Handling**: Define fallback behaviors
+
+## Example: Creating a Weather Tool
+
+Let's walk through creating a weather lookup tool:
+
+### Dashboard Configuration
+
+1. **Tool Name**: "Weather Lookup"
+2. **Description**: "Retrieves current weather information for any location"
+3. **Function Name**: `get_weather`
+4. **Parameters**:
+ - `location` (string, required): "The city or location to get weather for"
+5. **Server URL**: `https://api.openweathermap.org/data/2.5/weather`
+
+
+This example uses OpenWeatherMap's free API. You'll need to sign up at [openweathermap.org](https://openweathermap.org/api) to get a free API key and add it as a query parameter: `?appid=YOUR_API_KEY&q={location}`
+
+
+### Messages Configuration
+
+- **Request Start**: "Let me check the current weather for you..."
+- **Request Complete**: "Here's the weather information you requested."
+- **Request Failed**: "I'm having trouble accessing weather data right now."
+
+## Using Tools in Assistants
+
+Once created, your tools can be easily added to any assistant:
+
+### In the Dashboard
+
+1. Go to **Assistants** → Select your assistant
+2. Navigate to the **Tools** tab
+3. Click **Add Tool** and select your custom tool from the dropdown
+4. Save your assistant configuration
+
+### In Workflows
+
+Tools created in the Tools section are automatically available in the workflow builder:
+
+1. Add a **Tool Node** to your workflow
+2. Select your custom tool from the **Tool** dropdown
+3. Configure any node-specific settings
+
+## Alternative: API Configuration
+
+For advanced users who prefer programmatic control, you can also create and manage tools via the Vapi API:
+
+### Creating Tools via API
+
+```bash
+curl --location 'https://api.vapi.ai/tool' \
+--header 'Content-Type: application/json' \
+--header 'Authorization: Bearer ' \
+--data '{
"type": "function",
- "messages": [
- {
- "type": "request-start",
- "content": "Checking the weather forecast. Please wait..."
- },
- {
- "type": "request-complete",
- "content": "The weather in location is"
- },
- {
- "type": "request-failed",
- "content": "I couldn't get the weather information right now."
- },
- {
- "type": "request-response-delayed",
- "content": "It appears there is some delay in communication with the weather API.",
- "timingMilliseconds": 2000
- }
- ],
"function": {
"name": "get_weather",
+ "description": "Retrieves current weather information for any location",
"parameters": {
"type": "object",
"properties": {
"location": {
- "type": "string"
+ "type": "string",
+ "description": "The city or location to get weather for"
}
- }
- },
- "description": "Retrieves the current weather for a specified location."
+ },
+ "required": ["location"]
+ }
},
- "async": false,
"server": {
- "url": "https://your-weather-api.com/weather"
+ "url": "https://api.openweathermap.org/data/2.5/weather"
}
-}
+}'
```
-### Adding More Tools
+### Adding Tools to Assistants via API
-Simply create additional tool objects within the "tools" array, following the same structure and modifying the details as needed. Each tool can have its own unique configuration and messages.
+```bash
+curl --location --request PATCH 'https://api.vapi.ai/assistant/ASSISTANT_ID' \
+--header 'Authorization: Bearer ' \
+--header 'Content-Type: application/json' \
+--data '{
+ "model": {
+ "provider": "openai",
+ "model": "gpt-4",
+ "toolIds": ["your-tool-id-here"]
+ }
+}'
+```
## Request Format: Understanding the Tool Call Request
@@ -125,7 +164,7 @@ When your server receives a tool call request from Vapi, it will be in the follo
"description": "Retrieves the current weather for a specified location"
},
"server": {
- "url": "https://your-api-server.com/weather"
+ "url": "https://api.openweathermap.org/data/2.5/weather"
},
"messages": [],
"toolCall": {