# RevCent AI Voice Agents Overview

RevCent AI Voice Agents allow ecommerce businesses to accept inbound calls or make outbound calls using AI. The AI speaks directly with callers, follows markdown instructions, can use dynamic Handlebars data, and can be given opt-in system actions for looking up customers, retrieving sales, issuing refunds, adding cards, sending emails, triggering Functions, and more.

Source:
- RevCent MCP/API operations:
  - `CreateAIVoiceAgent`
  - `EditAIVoiceAgent`
  - `TriggerAIVoiceAgent`
  - `GetAIVoiceAgent`
  - `GetAIVoiceAgents`
- RevCent Knowledge Base: AI Voice Agents — `https://kb.revcent.com/tools/ai/voice-agents`

---

## What AI Voice Agents Do

AI Voice Agents can answer inbound phone calls, make outbound phone calls, match inbound callers to existing customers by phone number, use item and customer data inside instructions, follow structured markdown conversation instructions, use Handlebars to compile call-specific instructions, use reusable AI Voice Snippets, use pre-agent Functions to generate custom instruction content, use filter Functions to decide whether outbound event calls should run, and use system actions during calls when explicitly enabled.

Built-in features include inactivity detection, voicemail detection for outbound calls, robocall detection for inbound calls, call transfer, end-call instructions, active windows, and call limits.

---

## Ecommerce Use Cases

| Use Case | Call Method | Example |
|---|---|---|
| Inbound customer service | `inbound` | Customer calls support, AI looks up customer and helps with order, refund, shipment, or subscription questions. |
| Declined payment recovery | `outbound` | Customer attempts checkout and payment is declined; AI calls to help add a new card or complete the pending sale. |
| Outbound sales | `outbound` | Prospect enters a campaign or no-sale group; AI calls later with a campaign-specific offer. |
| Subscription retention | `outbound` | Renewal fails or subscription becomes overdue; AI calls to help update payment information. |
| Shipment support | `inbound` or `outbound` | AI checks shipment status and explains tracking details. |
| Chargeback prevention | `inbound` or `outbound` | AI detects or responds to refund/chargeback concerns and follows escalation rules. |

---

# How AI Voice Agents Can Help Ecommerce Businesses

AI Voice Agents can help ecommerce businesses wherever phone conversations are valuable but human availability, speed, consistency, or scale is a constraint.

They are especially useful for workflows where the business needs to:

- Answer common customer questions quickly.
- Recover lost revenue from declined or abandoned purchases.
- Help customers complete checkout.
- Reduce support backlog.
- Improve subscription retention.
- Follow up on high-value leads.
- Provide shipment and order status.
- Handle refund or cancellation requests according to policy.
- Escalate urgent or high-risk situations to humans.
- Collect structured call outcomes for reporting.
- Trigger downstream automation after a call.
- Measure AI Voice Agent performance using AI Voice Calls and API Calls in BigQuery.

AI Voice Agents should not be treated as generic “phone bots.” Each agent should have a specific job, clear instructions, carefully selected system actions, call limits, well-defined boundaries, and correct use of filter Functions, pre-agent Functions, and compile-time input data.

---

## High-Level Agent Type Categories

Most ecommerce AI Voice Agents fit into one of these categories:

| Agent Category | Primary Goal | Typical Call Method |
|---|---|---|
| Customer support agent | Answer inbound customer questions and resolve routine issues. | `inbound` |
| Order status agent | Help customers understand order, payment, and shipment status. | `inbound` |
| Declined payment recovery agent | Recover failed or declined sales by helping customers update payment or complete checkout. | `outbound` |
| Abandoned checkout / pending sale agent | Follow up after a customer starts checkout but does not complete payment. | `outbound` |
| Subscription retention agent | Help customers resolve failed renewals, overdue subscriptions, cancellations, or update-payment needs. | `outbound` or `inbound` |
| Trial conversion agent | Help customers convert before or after a trial expires. | `outbound` |
| Shipping support agent | Answer delivery, tracking, address, or fulfillment questions. | `inbound` or `outbound` |
| Refund and cancellation triage agent | Collect refund/cancel reasons, apply policy, and escalate where needed. | `inbound` |
| Chargeback prevention agent | Respond to unhappy customers and route risky situations before a dispute occurs. | `inbound` or `outbound` |
| Fraud/risk verification agent | Verify suspicious or high-risk orders before fulfillment. | `outbound` |
| VIP / high-value customer agent | Provide priority follow-up for important customers or high-value orders. | `outbound` or `inbound` |
| Lead qualification agent | Call prospects or new leads and qualify intent. | `outbound` |
| Winback agent | Re-engage lapsed customers with approved offers. | `outbound` |
| Post-purchase satisfaction agent | Check in after delivery or purchase and capture feedback. | `outbound` |
| Internal alert / ops call agent | Call internal team members when urgent events occur. | `outbound` |

---

# Example AI Voice Agent Ideas for Ecommerce

## 1. Inbound Customer Support Agent

**Purpose:** Answer routine customer questions and reduce support workload.

**Call method:** `inbound`

**Best for:**

- “Where is my order?”
- “Can I update my shipping address?”
- “What did I purchase?”
- “Can I get help with my subscription?”
- “Can I talk to someone?”

**Typical system actions:**

```text
SearchCustomers
GetCustomer
GetSale
GetShipment
GetSubscription
GetSubscriptionRenewal
CreateNote
InsertMetadata
```

**Use with caution:**

```text
RefundTransaction
CancelSubscription
EditSubscription
EditShipment
```

Only include these if the business has clear rules and wants the AI to perform those actions.

**Example behavior:**

The caller phones the support number. If the phone number matches a customer, the agent greets them by first name but still follows verification rules before discussing private details. If the customer asks about an order, the agent retrieves the customer record, finds the relevant sale or shipment, explains the status, creates a note, and ends the call or transfers if needed.

---

## 2. Declined Payment Recovery Agent

**Purpose:** Recover revenue after a failed or declined purchase attempt.

**Call method:** `outbound`

**Likely trigger:**

```text
sale.created.failed.declined
```

**Best for:**

- Failed checkout attempts.
- Pending sales that did not complete.
- Soft declines where the customer may successfully retry.
- High-value carts worth recovering.

**Typical system actions:**

```text
GetCustomer
GetSale
AddCardToCustomer
ProcessPendingSale
CreateNote
InsertMetadata
```

**Recommended filters:**

- Campaign filter for specific campaigns.
- Status filter for pending or recoverable sales.
- Metadata filter for AI-call-eligible records.
- Filter Function to skip customers who opted out or sales that are no longer recoverable.
- Decline-reason filter to avoid futile calls when the card is invalid, stolen, closed, restricted, fraud-related, or marked do-not-retry.

**Important instruction rules:**

- Clearly explain why the agent is calling.
- Do not pressure the customer.
- Verify identity before discussing payment details.
- Only collect card details if `AddCardToCustomer` is enabled and the customer agrees.
- Limit payment retry attempts.
- Do not call or retry the same card when hard-decline logic indicates the attempt is unlikely to recover.
- Create a note and metadata outcome after the call.

**Example outcome metadata:**

```text
ai_voice_decline_recovery_called = true
ai_voice_decline_recovery_outcome = payment_completed
ai_voice_decline_recovery_outcome = customer_declined
ai_voice_decline_recovery_outcome = no_answer
```

---

## 3. Abandoned Checkout / Pending Sale Agent

**Purpose:** Follow up with customers who started checkout but did not complete payment.

**Call method:** `outbound`

**Likely trigger:**

```text
sale.created.success.pending
sale.created.success.pending.is_upsell
sale.created.failed
```

**Best for:**

- Customers who left checkout before paying.
- Customers who had a technical issue during checkout.
- High-value carts.
- Upsell flows where payment is pending.

**Typical system actions:**

```text
GetCustomer
GetSale
EstimateSale
ProcessPendingSale
CreateNote
InsertMetadata
SendSMTPMessage
```

**Optional pre-agent Function use:**

A pre-agent Function can generate offer logic, such as:

```json
{
  "offer_allowed": true,
  "offer_text": "Free shipping is available if the customer completes the order today.",
  "max_discount_percent": 10
}
```

**Example behavior:**

The agent waits a configured delay after the pending sale event, then calls the customer. It explains that the customer appeared to have trouble completing checkout, offers help, answers product/order questions, and only processes payment if the customer clearly agrees.

---

## 4. Subscription Renewal Recovery Agent

**Purpose:** Reduce churn by helping customers fix failed subscription renewals.

**Call method:** `outbound`

**Likely trigger:**

```text
subscription_renewal.updated.failed
subscription.updated.status.overdue
```

**Best for:**

- Failed recurring billing.
- Expired or replaced cards.
- Overdue subscriptions.
- Customers at risk of involuntary churn.

**Typical system actions:**

```text
GetCustomer
GetSubscription
GetSubscriptionRenewal
AddCardToCustomer
RenewSubscription
CreateNote
InsertMetadata
SendSMTPMessage
```

**Use with caution:**

```text
CancelSubscription
SuspendSubscription
EditSubscription
RefundSubscriptionRenewal
```

**Important instruction rules:**

- Explain the subscription issue clearly.
- Verify the customer before discussing account details.
- Ask whether the customer wants to keep the subscription active.
- Add or update payment only with explicit consent.
- Do not cancel or change the subscription unless the customer requests it and the action is enabled.
- Create a note summarizing the call.

---

## 5. Trial Conversion Agent

**Purpose:** Help trial users convert to paying customers.

**Call method:** `outbound`

**Likely triggers:**

```text
trial.created
trial.updated.expired.failed
trial.updated.expired.success
trial.updated.cancelled
```

**Best for:**

- Trials that are about to expire.
- Trials that failed to convert.
- High-value trial customers.
- Customers who need help understanding the product.

**Typical system actions:**

```text
GetCustomer
GetTrial
GetSubscription
AddCardToCustomer
CreateSale
CreateNote
InsertMetadata
SendSMTPMessage
```

**Example behavior:**

The agent calls before or shortly after trial expiration, explains the next step, answers questions, and helps the customer continue if they want. If the customer is not interested, the agent records the reason using metadata or a note.

---

## 6. Shipping and Delivery Support Agent

**Purpose:** Help customers with delivery questions and reduce shipping-related support tickets.

**Call method:** `inbound` or `outbound`

**Likely triggers for outbound:**

```text
shipping.created
shipping.updated.shipped
shipping.updated.delivered
shipping.updated.ship_to
```

**Best for:**

- “Where is my package?”
- “Can I update my address?”
- “My package says delivered but I did not receive it.”
- “When will my order ship?”

**Typical system actions:**

```text
SearchCustomers
GetCustomer
GetSale
GetShipment
CreateNote
InsertMetadata
SendSMTPMessage
```

**Use with caution:**

```text
EditShipment
RefundShipment
```

Only include if the business wants the AI to update shipment details or refund shipping.

**Example behavior:**

The inbound caller asks about a shipment. The agent verifies the customer, retrieves shipment details, explains the tracking status, sends a follow-up email if needed, and creates a note.

---

## 7. Refund and Cancellation Triage Agent

**Purpose:** Gather refund/cancellation context, apply policy, and reduce human support workload.

**Call method:** `inbound`

**Best for:**

- Refund requests.
- Cancellation requests.
- Order issue intake.
- Policy explanation.
- Routing complex cases to humans.

**Typical system actions:**

```text
SearchCustomers
GetCustomer
GetSale
GetTransaction
GetSubscription
GetPendingRefund
CreateNote
InsertMetadata
SendSMTPMessage
```

**Use with caution:**

```text
RefundTransaction
RefundProductSale
RefundShipment
RefundSubscriptionRenewal
CancelSubscription
CancelTrial
```

**Important instruction rules:**

- Verify the customer before discussing private account details.
- Explain policy clearly.
- Do not refund unless refund actions are enabled and policy conditions are met.
- Escalate edge cases.
- Record the refund/cancel reason in a note or metadata.
- Never argue with the customer.

---

## 8. Chargeback Prevention Agent

**Purpose:** Reduce disputes by identifying and de-escalating high-risk customer situations.

**Call method:** `inbound` or `outbound`

**Likely triggers for outbound:**

```text
note.created
chargeback.created
fraud_detection.created
pending_refund.created
```

**Best for:**

- Customers threatening chargebacks.
- Customers repeatedly contacting support.
- High-value refund disputes.
- Fraud/risk review follow-up.

**Typical system actions:**

```text
GetCustomer
GetSale
GetTransaction
CreateNote
InsertMetadata
SendSMTPMessage
AddFraudAlert
```

**Use with caution:**

```text
RefundTransaction
VoidSale
CancelSubscription
```

**Example behavior:**

If a note or risk signal indicates that a customer may dispute a transaction, the agent calls or handles inbound escalation, listens calmly, verifies identity, explains the order/refund/shipment status, and transfers to a human if the customer remains upset or requests escalation.

---

## 9. Fraud / Risk Verification Agent

**Purpose:** Verify suspicious or high-risk orders before fulfillment.

**Call method:** `outbound`

**Likely triggers:**

```text
fraud_detection.created
sale.updated.fraud_alert.added
sentinel.alert.fraud_detected
```

**Best for:**

- High-risk sales.
- Fraud alerts.
- Suspicious contact or payment patterns.
- Orders requiring manual verification before shipment.

**Typical system actions:**

```text
GetCustomer
GetSale
GetTransaction
GetShipment
CreateNote
InsertMetadata
AddFraudAlert
```

**Important instruction rules:**

- Do not accuse the customer of fraud.
- Ask neutral verification questions.
- Do not reveal internal fraud rules.
- If verification fails, create a note and escalate.
- Do not remove fraud controls unless explicitly allowed by business policy.

---

## 10. VIP / High-Value Customer Agent

**Purpose:** Provide premium service for valuable customers.

**Call method:** `inbound` or `outbound`

**Best for:**

- High lifetime value customers.
- High-value orders.
- VIP groups.
- Enterprise/B2B buyers.
- Customers with recent support issues.

**Typical system actions:**

```text
GetCustomer
GetSale
GetShipment
GetSubscription
CreateNote
InsertMetadata
SendSMTPMessage
TriggerFunction
```

**Pre-agent Function idea:**

Generate a VIP context object before the call:

```json
{
  "vip_tier": "gold",
  "preferred_offer": "free expedited shipping",
  "support_priority": "high",
  "account_manager_name": "Sarah"
}
```

**Example behavior:**

The agent provides a more personalized experience, uses the customer’s status and purchase history, and transfers to a human account manager when appropriate.

---

## 11. Outbound Lead Qualification Agent

**Purpose:** Call prospects or newly created customers to qualify interest.

**Call method:** `outbound`

**Likely triggers:**

```text
customer.created
customer.updated.customer_group.added
```

**Best for:**

- New leads.
- Prospects added to a customer group.
- Customers who requested a demo.
- High-intent form submissions.
- B2B ecommerce inquiries.

**Typical system actions:**

```text
GetCustomer
CreateNote
InsertMetadata
SendSMTPMessage
TriggerFunction
```

**Example metadata outcomes:**

```text
lead_qualified = true
lead_interest_level = high
lead_requested_callback = true
lead_not_interested = true
```

**Example behavior:**

The agent calls the prospect, asks a few qualifying questions, determines interest level, records the outcome, and optionally sends a follow-up email or triggers a CRM Function.

---

## 12. Winback / Reorder Agent

**Purpose:** Re-engage customers who have not purchased recently.

**Call method:** `outbound`

**Trigger style:**

Usually `on_demand` or triggered by a scheduled AI Assistant/Function workflow that identifies eligible customers.

**Best for:**

- Lapsed customers.
- Consumable products that need reordering.
- Seasonal reactivation campaigns.
- Customers who bought once but never returned.

**Typical system actions:**

```text
GetCustomer
CreateSale
EstimateSale
CreateNote
InsertMetadata
SendSMTPMessage
TriggerFunction
```

**Pre-agent Function idea:**

Generate recommended reorder product and offer:

```json
{
  "recommended_product": "90 Day Supply",
  "last_purchase_date": "2026-03-15",
  "offer": "10% off reorder",
  "offer_expires": "2026-06-01"
}
```

---

## 13. Post-Purchase Satisfaction Agent

**Purpose:** Improve customer experience and collect feedback after delivery or purchase.

**Call method:** `outbound`

**Likely triggers:**

```text
shipping.updated.delivered
sale.created.success.paid
```

**Best for:**

- Asking if the customer received the product.
- Capturing product feedback.
- Identifying support issues early.
- Encouraging repeat purchases.
- Preventing negative reviews or chargebacks.

**Typical system actions:**

```text
GetCustomer
GetSale
GetShipment
CreateNote
InsertMetadata
SendSMTPMessage
```

**Example behavior:**

The agent calls after delivery, confirms the customer received the product, asks if they need help, records feedback, and sends follow-up information when appropriate.

---

## 14. Internal Operations Alert Agent

**Purpose:** Call internal team members when urgent ecommerce events occur.

**Call method:** `outbound`

**Likely triggers:**

```text
sentinel.alert
sentinel.alert.firewall_block
fraud_detection.created
chargeback.created
payment_profile event via Function/AI workflow
```

**Best for:**

- Fraud spikes.
- Gateway issues.
- Fulfillment incidents.
- High-value chargebacks.
- Critical customer escalations.

**Typical system actions:**

```text
CreateNote
InsertMetadata
TriggerFunction
SendSMTPMessage
```

**Example behavior:**

Instead of calling a customer, the agent calls an internal phone number or team contact, summarizes the urgent issue, and records that the internal alert call was attempted.

---

# Choosing the Right Agent Type

Use this decision guide when deciding what kind of AI Voice Agent to create.

| Business Goal | Suggested Agent |
|---|---|
| Reduce support calls handled by humans | Inbound Customer Support Agent |
| Help callers find order status | Order Status / Shipping Support Agent |
| Recover failed payments | Declined Payment Recovery Agent |
| Recover abandoned checkout | Pending Sale / Abandoned Checkout Agent |
| Reduce subscription churn | Subscription Renewal Recovery Agent |
| Convert trial users | Trial Conversion Agent |
| Reduce refund workload | Refund and Cancellation Triage Agent |
| Prevent chargebacks | Chargeback Prevention Agent |
| Verify suspicious orders | Fraud / Risk Verification Agent |
| Follow up with high-value customers | VIP Customer Agent |
| Qualify new leads | Lead Qualification Agent |
| Reactivate old customers | Winback / Reorder Agent |
| Collect post-delivery feedback | Post-Purchase Satisfaction Agent |
| Alert internal teams | Internal Operations Alert Agent |

---

# Agent Design Examples by Business Model

## Physical Product Store

Useful agents:

- Inbound support agent
- Shipping support agent
- Post-purchase satisfaction agent
- Refund triage agent
- Fraud verification agent
- Winback/reorder agent

Common system actions:

```text
SearchCustomers
GetCustomer
GetSale
GetShipment
CreateNote
InsertMetadata
SendSMTPMessage
```

---

## Subscription Business

Useful agents:

- Subscription renewal recovery agent
- Subscription cancellation triage agent
- Trial conversion agent
- Inbound subscription support agent
- Failed payment recovery agent

Common system actions:

```text
GetCustomer
GetSubscription
GetSubscriptionRenewal
AddCardToCustomer
RenewSubscription
CreateNote
InsertMetadata
SendSMTPMessage
```

Use cancellation and refund actions only with strict rules.

---

## Digital Product Business

Useful agents:

- Inbound access/support agent
- Failed payment recovery agent
- Refund triage agent
- Trial conversion agent
- VIP customer agent

Common system actions:

```text
SearchCustomers
GetCustomer
GetSale
GetTransaction
CreateNote
InsertMetadata
SendSMTPMessage
TriggerFunction
```

---

## High-Ticket / B2B Ecommerce

Useful agents:

- Lead qualification agent
- VIP follow-up agent
- Abandoned quote/checkout agent
- Internal alert agent
- Post-purchase onboarding agent

Common system actions:

```text
GetCustomer
GetSale
EstimateSale
CreateNote
InsertMetadata
SendSMTPMessage
TriggerFunction
```

Pre-agent Functions are especially useful for pulling CRM context, account manager details, or custom offer rules before the call.

---
---

# Outbound Delay Strategy and Customer Experience

For outbound AI Voice Agents, delay settings are extremely important.

A delay controls how long RevCent waits after an event before attempting the outbound call.

This matters most when the customer may still be actively doing something, especially checkout.

Examples:

```text
Pending checkout
Failed payment
Declined card
Trial expiration payment failure
Subscription renewal failure
Upsell pending sale
```

Calling too quickly may disturb the customer.

The customer may still be:

- Attempting checkout
- Correcting billing information
- Trying another card
- Checking a bank app
- Completing 3DS verification
- Deciding whether to complete an order
- Reviewing an upsell
- Resolving the issue without help

If the AI Voice Agent calls too soon, the call can distract the customer, make the customer feel monitored, create pressure, or even reduce the chance they complete the purchase.

---

## Delay Is a Customer Experience Decision

Delay should not be treated as a random technical setting.

It should be chosen based on:

- The event type
- The customer’s likely next action
- The urgency of the business goal
- Whether the call is likely to help or interrupt
- Product value
- Checkout complexity
- Whether the customer requested help
- Whether filters can detect if the issue was resolved

For checkout events, a short delay can give the customer time to complete the purchase before the AI Voice Agent calls.

---

## When Fast Calling May Still Make Sense

A call during or shortly after checkout may still make sense if the customer appears to need immediate help.

Examples:

```text
Customer entered incorrect information.
Customer had repeated checkout failures.
Customer is attempting a high-value purchase.
Customer requested assistance or a callback.
Payment failure looks fixable with help.
Customer is known to prefer phone help.
```

In those cases, a short delay or immediate call may be useful, but the agent’s instructions should be gentle and assistance-focused.

The agent should not pressure the customer or imply they did something wrong.

---

## Filters Are Checked After the Delay

Delay does not guarantee the call will happen.

For outbound event-based calls, filters are still checked after the delay expires.

This includes:

- Event filters
- Status filters
- Campaign filters
- Metadata filters
- Customer filters
- Call limits
- Active window checks
- Filter Function result

If a filter Function is configured, it must still return:

```javascript
callback(null, 'pass');
```

after the delay expires.

If the filter Function returns:

```javascript
callback(null, 'fail');
```

the call should not happen.

---

## Why Post-Delay Filtering Is Important

Post-delay filtering prevents unnecessary calls.

Example:

```text
Customer has failed checkout
  ↓
Agent waits 10 minutes
  ↓
Customer completes checkout on their own
  ↓
Filters run after delay
  ↓
Sale no longer qualifies
  ↓
No call is made
```

This prevents awkward calls like:

```text
"We noticed you had trouble checking out"
```

after the customer already completed the order.

---

## Best Practice

For outbound AI Voice Agents, especially checkout recovery agents:

```text
Use an intentional delay.
Use filters and filter Functions that re-check the current state after the delay.
Write agent instructions that acknowledge the customer may already be done or still checking out.
Make the call feel helpful, not disruptive.
```

Example customer-friendly instruction:

```markdown
# Checkout Timing and Customer Respect
- This call may happen shortly after the customer attempted checkout.
- The customer may still be checking out or may have already completed the purchase.
- Open gently and offer help.
- Ask whether now is a good time.
- If the customer is busy, still checking out, or already finished, politely end the call.
```

Delay strategy is part of customer experience design.


# Practical Agent Planning Template

Before creating an AI Voice Agent, define the agent in plain language:

```text
Agent name:
Call method:
Primary audience:
Trigger:
Trigger item type:
Delay strategy:
Main goal:
Successful call outcome:
Allowed system actions:
Actions that must never happen:
Verification rules:
Transfer rules:
Call limits:
Active window:
Metadata to insert:
Notes to create:
Email follow-up:
Pre-agent Function needed?
Filter Function needed?
Should the filter Function re-check current state after delay?
Live-call TriggerFunction needed?
```

Example:

```text
Agent name: Outbound - Declined Sale Recovery
Call method: outbound
Trigger: sale.created.failed.declined
Trigger item type: sale
Main goal: Help customer complete a pending sale after a declined payment.
Successful call outcome: Customer authorizes retry and payment succeeds, or customer declines and reason is recorded.
Allowed system actions: GetCustomer, GetSale, AddCardToCustomer, ProcessPendingSale, CreateNote, InsertMetadata.
Actions that must never happen: Refunds, voids, subscription changes, or unauthorized payment attempts.
Verification rules: Confirm customer identity before discussing sale details.
Transfer rules: Transfer if customer requests human help or is upset.
Call limits: max_calls_per_item = 1, max_outbound_calls_per_customer = 1.
Active window: 9 AM to 6 PM account timezone.
Metadata to insert: ai_voice_called, ai_voice_outcome.
```

This kind of planning ensures the AI Voice Agent is specific, safe, and useful.

---

# Getting Started

Before creating AI Voice Agents:

1. Contact RevCent to enable AI Voice Agent capabilities.
2. Create OpenAI and Twilio accounts.
3. Add payment methods to both accounts and ensure they are not in trial mode.
4. Create RevCent third-party integrations for OpenAI and Twilio.
5. Select a realtime AI model for OpenAI, such as a `gpt-realtime-*` model.
6. Select the Twilio phone number to use.
7. Create the AI Voice Agent disabled first.
8. Test carefully before enabling production calls.

Current schema support:

- AI realtime provider: OpenAI with `gpt-realtime-*`.
- Voice/phone provider: Twilio.
- Schema voice enum values: `marin`, `cedar`.

---

# Inbound vs Outbound

## Inbound

Inbound agents answer calls made to the configured Twilio number. RevCent attempts to match the caller phone number to an existing customer. If a match is found, the call can include customer context. If no match is found, the AI can use enabled system actions such as `SearchCustomers` if instructions tell it to do so.

## Outbound

Outbound agents make calls based on either an account event or an on-demand trigger.

| Trigger | Description |
|---|---|
| `account_event` | Calls automatically when a configured RevCent account event occurs. |
| `on_demand` | Calls when triggered by API or AI system tool using `TriggerAIVoiceAgent`. |

---

# Trigger Settings for Outbound Agents

Trigger settings apply only when `call_method` is `outbound`.

## Account Event Trigger

Examples:

```text
sale.created.failed.declined
customer.created
customer.updated.customer_group.added
subscription_renewal.updated.failed
trial.updated.expired.failed
shipping.updated.shipped
chargeback.created
```

Use the most specific notation possible.

## Delay

Use delay when the customer should have time to act before receiving a call. The KB notes a default minimum of 1 minute and maximum of 3 days.

## Filters

Supported filters include campaign filters, status filters, and metadata filters. Metadata filters require all specified name/value pairs to match.

## Max Calls Per Item

Recommended:

```text
max_calls_per_item = 1
```

This prevents repeat calls for the same item when the AI’s action creates another triggering event.

---

# On-Demand Outbound Trigger

On-demand outbound agents can be triggered by API using `TriggerAIVoiceAgent` or by AI as a system tool.

Requirements:

- Agent `call_method` must be `outbound`.
- Agent trigger must be `on_demand`.
- A valid `item_type` and `item_id` must be provided.

Supported trigger item types:

```text
sale
customer
product_sale
shipping
subscription
subscription_renewal
salvage_transaction
transaction
chargeback
fraud_detection
```

---

# Agent Instructions

Agent instructions are the most important part of the AI Voice Agent. They are written in Markdown and compiled for each call.

Recommended sections:

```markdown
# Role & Objective
# Personality & Tone
# Language
# Conversation Flow
# Verification Rules
# Payment Rules
# Refund Rules
# Escalation Rules
# Tool Usage Rules
# Close / End Call
```

Instructions can use Handlebars:

```handlebars
{{#if customer.verified}}
- Address the customer by first name: {{customer.first_name}}.
{{else}}
- Use a generic friendly greeting.
{{/if}}
```

Use triple braces with `toString` to embed JSON objects or arrays:

```handlebars
{{{toString item.item_details}}}
{{{toString pre_agent_function.response.product_list}}}
```

---

# Handlebars Data

The instruction compiler may provide:

```json
{
  "call_method": "inbound",
  "agent": {
    "id": "Vk7ar0u9RY9ol9WBBv70",
    "name": "MyAgent"
  },
  "item": {
    "has_item_details": true,
    "item_type": "customer",
    "item_id": "JBAy1XMbGAcm1pbQ57l9",
    "item_details": {}
  },
  "customer": {
    "verified": true,
    "id": "Bv70Vk7ar0u9R9WBY9ol",
    "first_name": "George",
    "last_name": "Washington",
    "email": "george@example.com",
    "phone": "202-456-1111"
  },
  "pre_agent_function": {
    "has_response": true,
    "response": {}
  },
  "snippets": {
    "card_guidelines": "Do not interrupt while the caller provides card information."
  }
}
```

Availability varies by call method, trigger type, customer match, and whether a pre-agent Function is configured.

---

# AI Voice Snippets

AI Voice Snippets are reusable instruction blocks. Use snippets for card collection rules, refund policy, compliance language, transfer rules, brand voice, identity verification rules, and common closing language.

Example usage:

```handlebars
{{snippets.card_guidelines}}
```

---

# System Actions

System actions are RevCent API operations the AI may call during the conversation. They are opt-in. Only enable actions the agent truly needs.

Examples include `SearchCustomers`, `GetCustomer`, `GetSale`, `AddCardToCustomer`, `ProcessPendingSale`, `CreateSale`, `GetShipment`, `RefundTransaction`, `CreateNote`, `SendSMTPMessage`, `TriggerFunction`, and `InsertMetadata`.

Do not enable refund, sale creation, add-card, or payment actions unless the instructions are strict and the workflow is tested.

---


# Filter Functions, Pre-Agent Functions, and Instruction Compile Data

AI Voice Agents can use several different types of dynamic data and Function behavior.

The three most important concepts are:

| Concept | When It Runs | Purpose |
|---|---|---|
| Filter Function | Before an outbound call proceeds. | Decide whether the call should happen. |
| Pre-Agent Function | Before instructions are compiled. | Generate custom data for Handlebars in the instructions. |
| Instruction Compile Data | During Handlebars compilation before the call. | Provide built-in RevCent call/item/customer context to the instructions. |

A fourth related concept is:

```text
TriggerFunction
```

which runs during the live call only if the AI Voice Agent has the `TriggerFunction` system action enabled.

---

---

# Detailed Filter, Pre-Agent, Customer, and Snippet Behavior

This section is especially important for MCP/API clients that need to create or edit AI Voice Agents correctly.

The AI Voice Agent system has four separate data/function concepts that must not be confused:

```text
Filter Function
Pre-Agent Function
Instruction input_data / Handlebars compile data
AI Voice Snippets
```

---

## Detailed Filter Function `pass` / `fail` Behavior

A filter Function is a gatekeeper for outbound AI Voice Agent calls.

It answers one question:

```text
Should this outbound AI Voice Agent call run for this item?
```

The filter Function receives item-specific data for the event or on-demand item, based on the triggering `item_type`.

Example data URL format:

```text
https://revcent.com/documentation/files/function/event/filter/[item_type].json
```

Examples:

```text
https://revcent.com/documentation/files/function/event/filter/customer.json
https://revcent.com/documentation/files/function/event/filter/sale.json
https://revcent.com/documentation/files/function/event/filter/shipping.json
https://revcent.com/documentation/files/function/event/filter/subscription.json
https://revcent.com/documentation/files/function/event/filter/subscription_renewal.json
https://revcent.com/documentation/files/function/event/filter/chargeback.json
https://revcent.com/documentation/files/function/event/filter/fraud_detection.json
```

The Function must return one of two exact single-term results:

```javascript
callback(null, 'pass');
```

or:

```javascript
callback(null, 'fail');
```

Meaning:

| Return | Meaning | Result |
|---|---|---|
| `pass` | The item passes the filter. | The AI Voice Agent call is allowed to run. |
| `fail` | The item fails the filter. | The AI Voice Agent call is blocked/skipped. |

Important:

```text
Default behavior is pass.
```

That means if the Function is not present, or if the filtering configuration does not block the item, the outbound call may proceed according to the rest of the agent trigger settings.

However, if a filter Function is used, the MCP should ensure the Function explicitly returns `pass` or `fail`.

---

## Filter Function Return Rules

A filter Function should not return:

```javascript
callback(null, true);
callback(null, false);
callback(null, { result: 'pass' });
callback(null, { status: 'fail' });
callback(null, 'approved');
callback(null, 'blocked');
```

Correct:

```javascript
callback(null, 'pass');
```

Correct:

```javascript
callback(null, 'fail');
```

The return must be a single term.

The MCP should write filter Functions so all code paths end in either `pass` or `fail`.

Example:

```javascript
exports.handler = async function(event, context, callback) {
  const item = event?.data?.item_details || {};

  if (item.metadata?.do_not_call === 'true') {
    return callback(null, 'fail');
  }

  if (item.customer?.phone_opt_out === true) {
    return callback(null, 'fail');
  }

  return callback(null, 'pass');
};
```

---

## When to Return `pass`

Return `pass` when the item is eligible for the outbound call.

Examples:

```text
Sale is still pending or recoverable.
Customer has not opted out.
Customer has a valid phone number.
Shipment event is important enough for a call.
Subscription renewal is still failed/overdue.
Customer is in the right campaign or shop.
Chargeback risk requires proactive outreach.
```

Example:

```javascript
if (item.status === 'pending' && item.customer?.phone) {
  return callback(null, 'pass');
}
```

---

## When to Return `fail`

Return `fail` when the call should not happen.

Examples:

```text
Customer opted out.
Customer has no usable phone number.
Customer is in a suppression group.
Sale is already paid or no longer recoverable.
Shipment is not customer-impacting.
Subscription was already renewed.
Customer has already been called enough times.
Customer is not in the correct campaign/shop/brand.
The item does not meet value or priority thresholds.
```

Example:

```javascript
if (!item.customer?.phone) {
  return callback(null, 'fail');
}
```

---

## Filter Functions Are for Eligibility, Not Agent Personalization

A filter Function is not the right place to generate dynamic call instructions.

Use a filter Function for:

```text
Should the call run?
```

Use a pre-agent Function for:

```text
What extra custom data should be available when compiling the instructions?
```

Use `TriggerFunction` for:

```text
What custom logic should the AI run during the live conversation?
```

---

# Detailed Pre-Agent Function Behavior

A pre-agent Function runs immediately before the AI Voice Agent instructions are compiled.

It receives call/item context and returns JSON data that becomes available to the instruction compiler.

A pre-agent Function is useful when the agent needs custom dynamic data that is not already available in the built-in instruction input data.

Examples:

```text
Brand name based on campaign
Custom offer based on customer value
Product list to mention during the call
Refund rules from an external system
CRM account status
Risk classification
Support priority
Approved talking points
Do-not-say instructions
```

---

## Pre-Agent Function Input Data URLs

For outbound calls triggered by account event or api_direct/on-demand, pre-agent Function input data uses this URL format:

```text
https://revcent.com/documentation/files/function/event/pre_agent/outbound/[item_type].json
```

Examples:

```text
https://revcent.com/documentation/files/function/event/pre_agent/outbound/customer.json
https://revcent.com/documentation/files/function/event/pre_agent/outbound/sale.json
https://revcent.com/documentation/files/function/event/pre_agent/outbound/shipping.json
https://revcent.com/documentation/files/function/event/pre_agent/outbound/subscription.json
https://revcent.com/documentation/files/function/event/pre_agent/outbound/subscription_renewal.json
https://revcent.com/documentation/files/function/event/pre_agent/outbound/chargeback.json
https://revcent.com/documentation/files/function/event/pre_agent/outbound/fraud_detection.json
```

For inbound calls, the pre-agent input data depends on whether the inbound caller phone number matches an existing customer.

Inbound with customer match:

```text
https://revcent.com/documentation/files/function/event/pre_agent/inbound/customer_match.json
```

Inbound with no customer match:

```text
https://revcent.com/documentation/files/function/event/pre_agent/inbound/no_customer_match.json
```

---

## What a Pre-Agent Function Should Return

A pre-agent Function should return a plain JSON object.

Example:

```javascript
callback(null, {
  company_name: 'Acme Inc.',
  allow_full_refunds: false,
  offer_allowed: true,
  offer_text: 'Free shipping is available if the customer completes the order today.',
  product_list: [
    {
      name: 'Product A',
      price: 29.99
    },
    {
      name: 'Product B',
      price: 49.99
    }
  ],
  support_priority: 'high'
});
```

The pre-agent response should be:

- JSON serializable
- Structured
- Predictable
- Safe to inject into instructions
- Specific to the call
- Free of secrets or private internal credentials
- Written so the instruction document can reference known paths

Avoid returning unclear freeform text that gives the AI unsafe latitude.

Poor return:

```javascript
callback(null, {
  text: 'Say whatever you need to make them buy.'
});
```

Better return:

```javascript
callback(null, {
  offer_allowed: true,
  approved_offer_name: 'Free Shipping Recovery Offer',
  approved_offer_terms: 'Free standard shipping if the customer completes payment today.',
  max_discount_percent: 0,
  must_not_offer: [
    'Cash refund',
    'Unapproved discount',
    'Guaranteed delivery date'
  ]
});
```

---

## How Pre-Agent Function Data Appears in Instruction Compile Data

When a pre-agent Function returns a valid JSON object, RevCent makes it available to the AI Voice Agent instruction compiler under:

```text
pre_agent_function
```

The structure is:

```json
{
  "pre_agent_function": {
    "has_response": true,
    "response": {
      "company_name": "Acme Inc.",
      "allow_full_refunds": false
    }
  }
}
```

Use this in Handlebars as:

```handlebars
{{pre_agent_function.response.company_name}}
```

or:

```handlebars
{{#if pre_agent_function.response.allow_full_refunds}}
- The agent may offer a full refund if the customer qualifies under the refund rules.
{{else}}
- The agent must not offer a full refund.
{{/if}}
```

Important:

```text
Access returned fields through pre_agent_function.response.*
```

Do not assume the returned values are at the top level.

Wrong:

```handlebars
{{company_name}}
```

Correct:

```handlebars
{{pre_agent_function.response.company_name}}
```

---

## Guarding Pre-Agent Function References

The MCP should use guards around pre-agent data because the Function may not run, may fail, or may return no usable data.

Recommended:

```handlebars
{{#if pre_agent_function.has_response}}
Use this custom context:
{{{toString pre_agent_function.response}}}
{{/if}}
```

For individual fields:

```handlebars
{{#if pre_agent_function.response.company_name}}
- Identify as {{pre_agent_function.response.company_name}} customer support.
{{else}}
- Identify as customer support.
{{/if}}
```

For JSON arrays or objects, use triple braces with `toString`:

```handlebars
# Available Products
{{{toString pre_agent_function.response.product_list}}}
```

---

## Good Pre-Agent Function Use Cases

Use a pre-agent Function when the instructions need call-specific content before the call begins.

Examples:

```text
Determine brand name from campaign.
Generate an approved offer from external CRM data.
Create a product list for a sales agent.
Return refund/cancellation rules for this customer.
Summarize customer risk or support priority.
Pull external subscription entitlement data.
Generate a personalized call objective.
Return internal escalation rules based on customer status.
```

A pre-agent Function is often better than `TriggerFunction` when the data is needed before the first words of the call.

---

## Pre-Agent Function vs AI Voice Snippets

Pre-agent Functions and AI Voice Snippets are different.

| Concept | Purpose |
|---|---|
| Pre-Agent Function | Generates dynamic JSON data before the call based on the call/item context. |
| AI Voice Snippet | Reusable instruction content that can be compiled and inserted into the main instructions. |

A pre-agent Function is best for data.

A snippet is best for reusable instruction text.

They can work together.

Example:

```handlebars
{{snippets.card_guidelines}}

{{#if pre_agent_function.response.company_name}}
- Brand voice: represent {{pre_agent_function.response.company_name}}.
{{/if}}
```

---

# Outbound Calls Always Include a Top-Level `customer` Object

For outbound AI Voice Agent calls, the instruction compile input data will always include a top-level `customer` object outside of the `item` object.

This is important for Handlebars safety and consistency.

The MCP should prefer:

```handlebars
{{customer.first_name}}
```

instead of trying to branch based on the outbound item type.

Do not require different customer paths like:

```handlebars
{{item.item_details.first_name}}
```

for `customer` item type, or:

```handlebars
{{item.item_details.customer.first_name}}
```

for non-customer item types.

For outbound calls, use the top-level customer object:

```handlebars
{{#if customer.first_name}}
- Address the customer as {{customer.first_name}}.
{{else}}
- Use a friendly generic greeting.
{{/if}}
```

This allows one instruction pattern to work across outbound calls for different item types.

---

## Why the Top-Level Customer Object Matters

Outbound calls can be triggered by many item types:

```text
customer
sale
shipping
subscription
subscription_renewal
chargeback
fraud_detection
```

The customer may live in different places inside each item’s raw details.

Examples:

```text
customer item_type:
item.item_details.first_name
```

```text
sale item_type:
item.item_details.customer.first_name
```

```text
shipping item_type:
item.item_details.customer.first_name
```

But RevCent provides a normalized top-level `customer` object for outbound instruction compilation.

Therefore, the MCP should write outbound instructions against:

```text
customer.first_name
customer.last_name
customer.email
customer.phone
customer.id
customer.verified
```

This keeps instructions cleaner and safer.

---

## Outbound Instruction Compile Data URLs

Outbound call instruction compile data examples use:

```text
https://revcent.com/documentation/files/ai_voice_agent/outbound/[item_type].json
```

Examples:

```text
https://revcent.com/documentation/files/ai_voice_agent/outbound/customer.json
https://revcent.com/documentation/files/ai_voice_agent/outbound/sale.json
https://revcent.com/documentation/files/ai_voice_agent/outbound/shipping.json
https://revcent.com/documentation/files/ai_voice_agent/outbound/subscription.json
https://revcent.com/documentation/files/ai_voice_agent/outbound/subscription_renewal.json
https://revcent.com/documentation/files/ai_voice_agent/outbound/chargeback.json
https://revcent.com/documentation/files/ai_voice_agent/outbound/fraud_detection.json
```

These are the correct examples for AI Voice Agent outbound instruction compile data.

Do not use Function account-event body URLs as outbound instruction compile-data examples.

---

# AI Voice Snippets

AI Voice Snippets are reusable pieces of instruction content that can be compiled and inserted into the main AI Voice Agent instructions.

The compiled snippets are available to the main instruction document through the `snippets` object.

Example input data structure:

```json
{
  "snippets": {
    "card_guidelines": "Do not interrupt if the caller is providing card information."
  }
}
```

Reference a snippet in the main instructions:

```handlebars
{{snippets.card_guidelines}}
```

Snippets are useful for reusable instruction blocks such as:

- Card handling rules
- Refund policy
- Verification rules
- Transfer rules
- Tone and compliance guidelines
- Subscription cancellation rules
- Chargeback escalation rules
- Shipping support rules
- Disclosure language
- End-call behavior

---

## Snippets Are Instruction Text, Not Data Fetching

AI Voice Snippets should be treated as reusable instruction content.

They should not be used as a replacement for:

- Pre-agent Functions
- Filter Functions
- System actions
- TriggerFunction
- Data retrieval operations

Use snippets when the same instruction section should be reused across multiple AI Voice Agents.

Use pre-agent Functions when dynamic data must be generated for a specific call.

---

## Snippet and Pre-Agent Function Example

Example main instruction pattern:

```handlebars
# Card Handling Rules
{{snippets.card_guidelines}}

# Brand Context
{{#if pre_agent_function.response.company_name}}
- Identify as {{pre_agent_function.response.company_name}}.
{{else}}
- Identify as customer support.
{{/if}}

# Product List
{{#if pre_agent_function.response.product_list}}
{{{toString pre_agent_function.response.product_list}}}
{{/if}}
```

This combines:

```text
Reusable rules from snippets
+
Dynamic call-specific data from pre_agent_function.response
```

---

# MCP Guidance for Data-Safe Instruction Writing

When writing AI Voice Agent instructions, MCP should:

1. Use top-level `customer.*` fields for outbound customer personalization.
2. Use `item.*` fields for the triggering item context.
3. Use `pre_agent_function.response.*` for pre-agent Function return values.
4. Use `snippets.*` for reusable compiled snippet content.
5. Use `{{#if ...}}` guards around optional data.
6. Use `{{{toString ...}}}` for objects and arrays.
7. Avoid referencing raw nested customer paths inside `item.item_details` when top-level `customer` is available.
8. Avoid using Function account-event body URLs as AI Voice Agent instruction compile-data examples.
9. Keep filter Functions limited to `pass` / `fail` eligibility decisions.
10. Keep pre-agent Functions focused on structured JSON data for instruction compilation.

## Filter Function

A filter Function decides whether an outbound AI Voice Agent call should happen.

It receives data specific to the `item_type` that triggered the AI Voice Agent.

Example input data URL format:

```text
https://revcent.com/documentation/files/function/event/filter/[item_type].json
```

Examples:

```text
https://revcent.com/documentation/files/function/event/filter/customer.json
https://revcent.com/documentation/files/function/event/filter/sale.json
https://revcent.com/documentation/files/function/event/filter/shipping.json
https://revcent.com/documentation/files/function/event/filter/subscription.json
https://revcent.com/documentation/files/function/event/filter/subscription_renewal.json
```

A filter Function should return either:

```javascript
callback(null, 'pass')
```

or:

```javascript
callback(null, 'fail')
```

Meaning:

```text
pass = allow the outbound call
fail = do not make the outbound call
```

Filter Functions are best for deciding whether the call is worth making, whether the customer is eligible, whether the item is recoverable, or whether the customer should be suppressed.

---

## Pre-Agent Function

A pre-agent Function runs before the AI Voice Agent instructions compile.

Its purpose is to create custom data for the agent instructions.

The pre-agent Function response becomes available in the compiled instructions as:

```text
pre_agent_function
```

Example use:

```handlebars
{{#if pre_agent_function.offer_allowed}}
Offer the customer: {{pre_agent_function.response.offer_text}}
{{/if}}
```

---

## Outbound Pre-Agent Function Input Data

For outbound calls fired by either:

```text
account_event
api_direct / on-demand
```

the pre-agent Function input data uses this URL:

```text
https://revcent.com/documentation/files/function/event/pre_agent/outbound/[item_type].json
```

Examples:

```text
https://revcent.com/documentation/files/function/event/pre_agent/outbound/customer.json
https://revcent.com/documentation/files/function/event/pre_agent/outbound/sale.json
https://revcent.com/documentation/files/function/event/pre_agent/outbound/shipping.json
https://revcent.com/documentation/files/function/event/pre_agent/outbound/subscription.json
https://revcent.com/documentation/files/function/event/pre_agent/outbound/subscription_renewal.json
```

---

## Outbound AI Voice Agent Instruction Compile Data

For outbound calls fired by either:

```text
account_event
api_direct / on-demand
```

the AI Voice Agent instructions compile with input data using:

```text
https://revcent.com/documentation/files/ai_voice_agent/outbound/[item_type].json
```

Examples:

```text
https://revcent.com/documentation/files/ai_voice_agent/outbound/customer.json
https://revcent.com/documentation/files/ai_voice_agent/outbound/sale.json
https://revcent.com/documentation/files/ai_voice_agent/outbound/shipping.json
https://revcent.com/documentation/files/ai_voice_agent/outbound/subscription.json
https://revcent.com/documentation/files/ai_voice_agent/outbound/subscription_renewal.json
```

Important:

```text
Outbound pre-agent Function input data and outbound instruction compile data are not the same schema.
```

---

## Inbound Pre-Agent Function Input Data

For inbound calls, the pre-agent Function input depends on whether the inbound caller number matches an existing customer.

Customer match:

```text
https://revcent.com/documentation/files/function/event/pre_agent/inbound/customer_match.json
```

No customer match:

```text
https://revcent.com/documentation/files/function/event/pre_agent/inbound/no_customer_match.json
```

---

## Inbound AI Voice Agent Instruction Compile Data

For inbound calls, the AI Voice Agent instruction compile data also depends on whether the caller number matches an existing customer.

Customer match:

```text
https://revcent.com/documentation/files/ai_voice_agent/inbound/customer_match.json
```

No customer match:

```text
https://revcent.com/documentation/files/ai_voice_agent/inbound/no_customer_match.json
```

The file name is `no_customer_match` for both inbound pre-agent Function input data and inbound AI Voice Agent instruction compile data when no customer match exists.

---

## Decision Table

| Call Scenario | Filter Function Input | Pre-Agent Function Input | Instruction Compile Data |
|---|---|---|---|
| Outbound account-event call for `[item_type]` | `https://revcent.com/documentation/files/function/event/filter/[item_type].json` | `https://revcent.com/documentation/files/function/event/pre_agent/outbound/[item_type].json` | `https://revcent.com/documentation/files/ai_voice_agent/outbound/[item_type].json` |
| Outbound api_direct / on-demand call for `[item_type]` | `https://revcent.com/documentation/files/function/event/filter/[item_type].json` if used | `https://revcent.com/documentation/files/function/event/pre_agent/outbound/[item_type].json` | `https://revcent.com/documentation/files/ai_voice_agent/outbound/[item_type].json` |
| Inbound call with customer match | Not applicable | `https://revcent.com/documentation/files/function/event/pre_agent/inbound/customer_match.json` | `https://revcent.com/documentation/files/ai_voice_agent/inbound/customer_match.json` |
| Inbound call with no customer match | Not applicable | `https://revcent.com/documentation/files/function/event/pre_agent/inbound/no_customer_match.json` | `https://revcent.com/documentation/files/ai_voice_agent/inbound/no_customer_match.json` |

---

## Function Triggered During Instructions

A Function triggered during the live call is different from a filter Function or pre-agent Function.

This requires the `TriggerFunction` system action.

Use it when the AI needs custom logic during the conversation, such as:

- Looking up external CRM data
- Generating a real-time offer
- Validating an external account number
- Calling an external eligibility API
- Logging call outcomes to a third-party system

Do not use `TriggerFunction` when the Function is only deciding whether the call should happen. Use a filter Function for that.

Do not use `TriggerFunction` when the Function should prepare instruction data before the call. Use a pre-agent Function for that.

# Active Window and Call Limits

Active windows restrict when the agent is active. For inbound calls, inactive calls can be forwarded to a fallback number if `inactive_forward_number` is provided.

Call limits include:

| Limit | Purpose |
|---|---|
| `max_outbound_calls_per_customer` | Outbound only. Prevents repeatedly calling the same customer. |
| `max_calls_per_day` | Caps total calls per day. `0` means no limit. |
| `max_duration` | Maximum call duration in minutes. Default is 15; KB notes max is 30. |

---

---

# AI Voice Agent Metrics, AI Voice Calls, API Calls, and BigQuery Reporting

AI Voice Agents become much more valuable when their call activity and system-action activity are measured.

RevCent stores AI Voice Call and API Call data in BigQuery, which allows ecommerce businesses to run reports on:

```text
Call volume.
Inbound vs outbound call performance.
Call completion/no-answer/error rates.
Average call duration.
Transfer rate.
Payment attempts during calls.
Successful vs failed payment-related actions.
Refund actions during calls.
Sale creation or pending-sale processing during calls.
System actions used by each AI Voice Agent.
Revenue-related performance by AI Voice Agent.
```

For reporting, metrics, analytics, aggregations, or data mining, MCP/AI should use:

```text
BigQueryRunQuery
```

Do not use paginated retrieval operations such as `GetAIVoiceCalls` for metrics, counts, dashboards, aggregations, or data mining.

---

## Core BigQuery Tables for AI Voice Agent Reporting

The most important tables are:

| Table | Purpose |
|---|---|
| `revcent.user.ai_voice_agent` | Contains AI Voice Agents created by the user. Useful for agent names, descriptions, call method, and enabled status. |
| `revcent.user.ai_voice_call` | Contains individual AI Voice Calls created when inbound or outbound calls occur. |
| `revcent.user.api_call` | Contains API/system actions, including actions associated with an AI Voice Agent or a specific AI Voice Call. |

Important relationships:

```text
ai_voice_call.ai_voice_agent → ai_voice_agent.id
api_call.ai_voice_agent → ai_voice_agent.id
api_call.ai_voice_call → ai_voice_call.id
```

Two reporting paths are especially important:

```text
Path 1: AI Voice Call reporting
ai_voice_agent → ai_voice_call

Path 2: System action / payment attempt reporting
ai_voice_agent → api_call
ai_voice_call → api_call
```

---

## Reporting Directly From `api_call.ai_voice_agent`

Not every useful AI Voice Agent report must start from the AI Voice Call table.

If an API call was made by an AI Voice Agent, the `api_call` table can include:

```text
api_call.ai_voice_agent
```

This allows reporting on AI Voice Agent actions even when the report is focused on system actions instead of call records.

Use this when the business question is action-focused:

```text
How many sale creation attempts did each AI Voice Agent make?
How many payment-related actions succeeded or failed?
How many refunds did each AI Voice Agent attempt?
How many notes were created by AI Voice Agents?
How many metadata inserts were performed by AI Voice Agents?
Which AI Voice Agent triggered the most Functions?
Which AI Voice Agent had the most API action errors?
```

Example:

```sql
SELECT
  ava.id AS ai_voice_agent_id,
  ava.name AS ai_voice_agent_name,
  ac.type AS api_call_type,
  ac.method AS api_call_method,
  COUNT(*) AS api_action_count,
  SUM(IF(ac.code = 1, 1, 0)) AS success_count,
  SUM(IF(ac.code != 1, 1, 0)) AS failure_count,
  ROUND(SUM(IF(ac.code = 1, 1, 0)) * 100.0 / COUNT(*), 2) AS success_rate_percent
FROM `revcent.user.api_call` ac
LEFT JOIN `revcent.user.ai_voice_agent` ava
  ON ac.ai_voice_agent = ava.id
WHERE ac.created_at >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
  AND ac.ai_voice_agent IS NOT NULL
GROUP BY
  ai_voice_agent_id,
  ai_voice_agent_name,
  api_call_type,
  api_call_method
ORDER BY api_action_count DESC
```

This report is useful for measuring what AI Voice Agents are doing across system actions.

---

## Reporting From `api_call.ai_voice_call`

When an API call is associated with a specific AI Voice Call, the `api_call` table can include:

```text
api_call.ai_voice_call
```

This allows a report to connect system actions to the exact call where they happened.

Use this when the business question is call-focused:

```text
Which specific calls attempted payment actions?
Which calls created sales?
Which calls attempted refunds?
Which calls created notes or inserted metadata?
Which calls had failed API actions?
Which calls triggered Functions?
Which calls sent emails?
```

Example:

```sql
SELECT
  avc.id AS ai_voice_call_id,
  ava.name AS ai_voice_agent_name,
  avc.call_method,
  avc.status AS call_status,
  avc.call_duration / 1000 AS call_duration_seconds,
  ac.type AS api_call_type,
  ac.method AS api_call_method,
  ac.code AS api_call_code,
  COUNT(*) AS api_action_count
FROM `revcent.user.api_call` ac
JOIN `revcent.user.ai_voice_call` avc
  ON ac.ai_voice_call = avc.id
LEFT JOIN `revcent.user.ai_voice_agent` ava
  ON avc.ai_voice_agent = ava.id
WHERE ac.created_at >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
  AND ac.ai_voice_call IS NOT NULL
GROUP BY
  ai_voice_call_id,
  ai_voice_agent_name,
  avc.call_method,
  call_status,
  call_duration_seconds,
  api_call_type,
  api_call_method,
  api_call_code
ORDER BY ai_voice_call_id, api_action_count DESC
```

This report is useful for auditing what happened during individual AI Voice Calls.

---

# Payment Attempt and Refund Reporting

AI Voice Agents may be enabled with payment, sale, card, or refund actions, such as:

```text
CreateSale
ProcessPendingSale
AddCardToCustomer
EstimateSale
VoidSale
RefundTransaction
RefundProductSale
RefundShipment
RefundSubscriptionRenewal
```

When these actions are used during or by AI Voice Agent workflows, they can be analyzed using the `api_call` table.

Useful payment and refund questions:

```text
How many payment attempts did AI Voice Agents make?
How many succeeded?
How many failed?
Which AI Voice Agent had the highest payment action success rate?
Which calls attempted payment recovery?
Which calls attempted refunds?
Which refund actions succeeded or failed?
Which AI Voice Agents are producing the most revenue-related activity?
```

Because the exact `api_call.type` and `api_call.method` values should be confirmed from the user's account data, MCP/AI should first discover the action values present.

---

## Discover Payment-Related API Actions

Start by grouping API Calls associated with AI Voice Agents.

```sql
SELECT
  ac.type,
  ac.method,
  COUNT(*) AS api_call_count,
  SUM(IF(ac.code = 1, 1, 0)) AS success_count,
  SUM(IF(ac.code != 1, 1, 0)) AS failure_count
FROM `revcent.user.api_call` ac
WHERE ac.created_at >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
  AND ac.ai_voice_agent IS NOT NULL
GROUP BY ac.type, ac.method
ORDER BY api_call_count DESC
```

Then refine the report around the exact `type` and `method` values that represent sale creation, payment processing, refunds, card actions, or other revenue-related behavior.

---

## Payment Action Success/Failure by AI Voice Agent

This query uses keyword matching to identify likely payment-related actions.

MCP/AI should refine it after inspecting real `type` and `method` values.

```sql
SELECT
  ava.id AS ai_voice_agent_id,
  ava.name AS ai_voice_agent_name,
  ac.type AS api_call_type,
  ac.method AS api_call_method,
  COUNT(*) AS payment_action_count,
  SUM(IF(ac.code = 1, 1, 0)) AS successful_payment_actions,
  SUM(IF(ac.code != 1, 1, 0)) AS failed_payment_actions,
  ROUND(SUM(IF(ac.code = 1, 1, 0)) * 100.0 / COUNT(*), 2) AS success_rate_percent
FROM `revcent.user.api_call` ac
LEFT JOIN `revcent.user.ai_voice_agent` ava
  ON ac.ai_voice_agent = ava.id
WHERE ac.created_at >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
  AND ac.ai_voice_agent IS NOT NULL
  AND REGEXP_CONTAINS(
    LOWER(CONCAT(ac.type, ' ', ac.method)),
    r'sale|payment|transaction|refund|card|pending'
  )
GROUP BY
  ai_voice_agent_id,
  ai_voice_agent_name,
  api_call_type,
  api_call_method
ORDER BY payment_action_count DESC
```

This can be used to compare AI Voice Agents by revenue-related action success/failure.

---

# AI Voice Agent Call Performance Report

This query joins AI Voice Calls to AI Voice Agents to measure call performance by agent.

```sql
SELECT
  ava.id AS ai_voice_agent_id,
  ava.name AS ai_voice_agent_name,
  ava.call_method AS configured_call_method,
  avc.call_method AS actual_call_method,
  COUNT(*) AS total_calls,
  SUM(IF(avc.status = 'Completed', 1, 0)) AS completed_calls,
  SUM(IF(avc.status = 'No Answer', 1, 0)) AS no_answer_calls,
  SUM(IF(avc.status = 'Voicemail', 1, 0)) AS voicemail_calls,
  SUM(IF(avc.status = 'Error', 1, 0)) AS error_calls,
  AVG(avc.call_duration) / 1000 AS avg_call_duration_seconds,
  SUM(IF(avc.call_transferred, 1, 0)) AS transferred_calls,
  ROUND(SUM(IF(avc.call_transferred, 1, 0)) * 100.0 / COUNT(*), 2) AS transfer_rate_percent
FROM `revcent.user.ai_voice_call` avc
LEFT JOIN `revcent.user.ai_voice_agent` ava
  ON avc.ai_voice_agent = ava.id
WHERE avc.created_at >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
GROUP BY
  ai_voice_agent_id,
  ai_voice_agent_name,
  configured_call_method,
  actual_call_method
ORDER BY total_calls DESC
```

This report can answer:

```text
Which AI Voice Agents are making or receiving the most calls?
Which agents have high no-answer or voicemail rates?
Which agents have high error rates?
Which agents transfer most often?
Which agents have unusually long or short calls?
```

---

# Combined Voice Agent Call + API Action Performance

This query combines call metrics with API action metrics.

It is useful for evaluating whether calls are producing actual operational outcomes.

```sql
SELECT
  ava.id AS ai_voice_agent_id,
  ava.name AS ai_voice_agent_name,
  COUNT(DISTINCT avc.id) AS calls_with_api_actions,
  COUNT(ac.id) AS total_api_actions,
  SUM(IF(ac.code = 1, 1, 0)) AS successful_api_actions,
  SUM(IF(ac.code != 1, 1, 0)) AS failed_api_actions,
  ROUND(SUM(IF(ac.code = 1, 1, 0)) * 100.0 / COUNT(ac.id), 2) AS api_action_success_rate_percent,
  SUM(IF(REGEXP_CONTAINS(LOWER(CONCAT(ac.type, ' ', ac.method)), r'sale|payment|transaction|refund|card|pending'), 1, 0)) AS payment_related_actions
FROM `revcent.user.api_call` ac
JOIN `revcent.user.ai_voice_call` avc
  ON ac.ai_voice_call = avc.id
LEFT JOIN `revcent.user.ai_voice_agent` ava
  ON avc.ai_voice_agent = ava.id
WHERE ac.created_at >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
GROUP BY
  ai_voice_agent_id,
  ai_voice_agent_name
ORDER BY payment_related_actions DESC, total_api_actions DESC
```

This can help answer:

```text
Which voice agents are doing the most operational work?
Which voice agents are successfully completing actions?
Which voice agents are involved in the most payment-related activity?
Which voice agents may need instruction/system-action refinement due to failed API calls?
```

---

# Revenue Performance Reporting

Revenue performance usually requires joining AI Voice Calls and API Calls to sale, transaction, subscription renewal, salvage transaction, or other payment-related tables.

The AI Voice Call table can provide:

```text
ai_voice_call.sale
ai_voice_call.customer
ai_voice_call.item_type
ai_voice_call.item_id
ai_voice_call.ai_voice_agent
```

The API Call table can provide:

```text
api_call.ai_voice_agent
api_call.ai_voice_call
api_call.type
api_call.method
api_call.code
```

A common starting point is to report related sale amount by AI Voice Agent.

Important:

```text
MCP/AI should always call GetBigQueryTables before writing final production SQL and confirm the exact sale/revenue field names.
```

Example schema-dependent query:

```sql
SELECT
  ava.id AS ai_voice_agent_id,
  ava.name AS ai_voice_agent_name,
  COUNT(DISTINCT avc.id) AS total_calls,
  COUNT(DISTINCT avc.customer) AS unique_customers,
  COUNT(DISTINCT avc.sale) AS related_sales,
  SUM(s.amount) AS related_sale_amount,
  AVG(avc.call_duration) / 1000 AS avg_call_duration_seconds,
  SUM(IF(avc.status = 'Completed', 1, 0)) AS completed_calls
FROM `revcent.user.ai_voice_call` avc
LEFT JOIN `revcent.user.ai_voice_agent` ava
  ON avc.ai_voice_agent = ava.id
LEFT JOIN `revcent.user.sale` s
  ON avc.sale = s.id
WHERE avc.created_at >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
GROUP BY
  ai_voice_agent_id,
  ai_voice_agent_name
ORDER BY related_sale_amount DESC
```

If the sale table does not use `amount`, replace `s.amount` with the confirmed revenue field.

For more accurate revenue attribution, the report may need to use:

```text
sale status
transaction status
successful payment API calls
salvage transaction outcome
metadata inserted by the voice agent
notes created after the call
time windows after the call
```

Example advanced attribution question:

```text
How much revenue was recovered within 24 hours after a declined-sale recovery voice call?
```

That type of report should join the AI Voice Call to sale/transaction/salvage tables and use a clear time window.

---

# Practical Voice Agent Performance KPIs

Useful KPIs include:

```text
Total calls by AI Voice Agent.
Completed calls by AI Voice Agent.
No-answer / voicemail / busy rates.
Average call duration.
Transfer rate.
API actions per call.
Payment-related API actions per call.
Payment action success rate.
Refund action count and success rate.
Sale creation or pending-sale processing attempts.
Revenue associated with AI Voice Agent calls.
Recovered revenue after outbound recovery calls.
Error rate for voice-agent API actions.
Notes created after calls.
Metadata outcomes inserted after calls.
```

These KPIs help ecommerce businesses evaluate whether AI Voice Agents are improving:

```text
Revenue recovery.
Customer support capacity.
Subscription retention.
Checkout completion.
Refund handling.
Shipment support.
Risk and chargeback prevention.
Operational efficiency.
```

---

# MCP/AI BigQuery Guidance for Voice Agent Metrics

When the user asks for AI Voice Agent reporting:

1. Use `BigQueryRunQuery`, not `GetAIVoiceCalls`, for metrics.
2. Call `GetBigQueryTables` first to confirm schemas.
3. Use `revcent.user.ai_voice_call` for call-level metrics.
4. Use `revcent.user.ai_voice_agent` for agent names and configured call method.
5. Use `revcent.user.api_call` for system-action, payment-attempt, refund, sale, metadata, note, email, and Function activity.
6. Use `api_call.ai_voice_call` when the report should connect actions to specific calls.
7. Use `api_call.ai_voice_agent` when the report should measure actions by voice agent even without grouping by call.
8. Join sale/transaction/salvage/subscription tables when revenue performance is requested.
9. Use date filters to reduce query cost and avoid timeouts.
10. Refine `api_call.type` and `api_call.method` filters after discovering actual account values.

# Best Practices

1. Create agents disabled first.
2. Test with a limited campaign or item set.
3. Use `max_calls_per_item = 1` for event-triggered outbound agents.
4. Use `max_outbound_calls_per_customer = 1` unless repeated calls are intentional.
5. Use active windows to prevent late outbound calls.
6. Use delay for event-triggered outbound calls.
7. Enable only necessary system actions.
8. Write strict instructions for payment, refund, and escalation behavior.
9. Use Handlebars for personalization.
10. Use pre-agent Functions for dynamic instruction data.
11. Use filter Functions for call eligibility.
12. Use `TriggerFunction` only for live-call custom actions.
13. Monitor early calls and refine instructions.
14. Use metadata to track AI outcomes.
15. Review costs and daily call limits.
16. Use BigQueryRunQuery with AI Voice Call and API Call tables for reporting, metrics, payment attempt analysis, and revenue performance.


---
Document Parent Directory
* [Operations](https://revcent.com/documentation/markdown/mcp/operation/index.md) - AI/MCP details and overviews for operations available within the RevCent MCP.