> ## Documentation Index
> Fetch the complete documentation index at: https://docs.revring.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent Tools

> Configure system and custom tools for your agents

Tools enable your AI agents to take actions during phone calls beyond just conversation. RevRing provides built-in system tools and supports custom tools via webhooks.

## System Tools

System tools are pre-built capabilities that agents can invoke during calls. These tools are configured in the **Tools** tab of your agent settings.

<Note>
  **Flow agents**: End Call, Transfer, and Press Digits are handled by dedicated [flow nodes](/platform/conversation-flows) instead of system tools. These three tools only appear on the Tools tab for single-prompt agents. Voicemail Detection and custom tools are available for both modes.
</Note>

### End Call

The End Call tool allows agents to automatically terminate calls based on configurable rules.

#### When to Use

* Calls that have reached their natural conclusion
* Customer explicitly ends the conversation
* Maximum conversation time is reached
* Call objective has been completed

#### Configuration

1. Navigate to the **Tools** tab
2. Locate **End Call** under System Tools
3. Toggle the switch to enable
4. Click **Configure** to customize behavior
5. Set **End Call Rules Override** to define when the agent should end calls:

```
End the call when:
- The customer says goodbye or indicates they're done
- The appointment has been confirmed
- The customer explicitly asks to end the call
- You've provided all requested information and there are no further questions
- The conversation has exceeded 5 minutes
```

6. Click **Save**

<Note>
  If you leave the rules override empty, RevRing uses sensible defaults. Custom rules give you more control over call termination behavior.
</Note>

#### How It Works

When enabled, the agent has access to an `end_call` function. During the conversation, if the agent determines (based on the rules) that the call should end, it will:

1. Invoke the `end_call` function
2. Speak a brief closing message
3. Terminate the call gracefully

You can see end call invocations in the call transcript labeled as "Tool: end\_call".

### Transfer

The Transfer tool enables agents to transfer calls to other phone numbers or departments based on conditions you define. RevRing supports two transfer modes: **cold** and **warm**.

#### When to Use

* Customer requests to speak with a human representative
* Issue requires specialized expertise beyond the agent's scope
* Escalation to management or specific departments
* Routing to on-call support staff

#### Configuration

1. Navigate to the **Tools** tab

2. Locate **Transfer** under System Tools

3. Toggle the switch to enable

4. Click **Configure** to set up transfer routes

5. Select the **Default Transfer Mode** (applied to any route that doesn't set its own mode):
   * **Cold Transfer** — the agent transfers the call immediately and disconnects
   * **Warm Transfer** — the agent places the caller on hold, calls the recipient to brief them, then connects the parties

6. Add transfer routes:

**Transfer Routes**:

* **To number**: `+12025559999` (destination phone number in E.164 format)
* **Extension** (optional): touch-tone digits dialed after the call connects, to reach an extension behind a phone menu or auto-attendant (e.g. `123#`). Allowed characters: `0-9`, `*`, `#`, and `w` for a 0.5-second pause. Sent on warm transfers only.
* **Condition**: `Transfer to sales team for pricing questions or to close deals`
* **Mode**: `Default`, `Cold`, or `Warm` — overrides the default transfer mode for this specific route

Click **Add route** to add multiple destinations.

**Transfer Description Override** (optional): Custom instructions for when the agent should offer a transfer.

7. Click **Save**

<Tip>
  You can configure multiple transfer routes for different scenarios. The agent will choose the appropriate route based on the conversation context and conditions you define.
</Tip>

<Tip>
  **Fallback chains**: Because each route can set its own mode, you can build a ring tree. For example, a warm transfer to a primary number, a warm transfer to a backup if the first isn't answered, and a final cold transfer as a last resort. When a warm transfer isn't answered, the agent continues to the next route based on your prompt and conditions. (Cold transfers hand off immediately and cannot fall back, so they belong last.)
</Tip>

#### Cold Transfer

In cold transfer mode, the agent invokes the `transfer_to_number` function and the call is immediately handed off to the destination number. RevRing's involvement ends — billing stops and recording stops once the transfer is initiated.

The transfer appears in the call transcript as a `transfer_to_number` tool invocation.

<Note>
  **Provider Setup Required**: Ensure your SIP trunk provider supports SIP REFER and has call transfers enabled. Some providers like Twilio require enabling **PSTN Transfer** in your trunk settings. See the [Telephony Setup](/platform/telephony) guide for details.
</Note>

#### Warm Transfer

Warm transfer provides a more seamless handoff. When the agent decides to transfer:

1. The **caller is placed on hold** — they hear a hold message and optional hold music
2. The **agent calls the recipient** at the transfer destination number
3. The agent **briefs the recipient** with a summary of the conversation so far
4. The **caller is connected** to the recipient

Warm transfer is configured with the following settings:

| Setting                              | Description                                                                                                                                          |
| ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Hold Message**                     | Message spoken to the caller while on hold (e.g., "Please hold while I transfer you.") Max 500 characters.                                           |
| **Hold Music**                       | Enable or disable hold music while the caller waits                                                                                                  |
| **Summary Instructions**             | Extra guidance for the AI when briefing the human agent. Max 2,000 characters. If omitted, a default summary is generated.                           |
| **Intro Message**                    | Spoken after the human agent accepts, heard by both parties (e.g., "You're now connected. They're up to speed on your request.") Max 500 characters. |
| **Continue Recording After Handoff** | Keep recording after the agent hands off, so the recording also includes the human agent and caller conversation.                                    |

<Note>
  **Reaching an extension**: If a route has an **Extension**, the agent dials it as touch tones once the recipient's line connects, so you can reach a specific extension behind a phone menu or auto-attendant. Add `w` to insert a 0.5-second pause if the menu needs a moment before it accepts input (e.g. `w123#`). Extensions are dialed on warm transfers only, because a cold transfer hands the call off immediately.
</Note>

#### Configuring via API

Set `transferMode` (the default mode) and `warmTransferConfig` when creating or updating an agent. Each route may include an optional `mode` (`"cold"` or `"warm"`) that overrides the default for that route; omit it to inherit `transferMode`. The example below builds a warm primary, warm backup, then cold last-resort fallback chain:

```bash theme={null}
curl -X PATCH https://api.revring.ai/v1/agents/{agentId} \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "transferEnabled": true,
    "transferMode": "warm",
    "transferRoutes": [
      {
        "to_number": "+12025559999",
        "condition": "Primary: transfer to the support team",
        "mode": "warm",
        "extension": "123#"
      },
      {
        "to_number": "+12025550000",
        "condition": "Backup: use if the primary line is not answered",
        "mode": "warm"
      },
      {
        "to_number": "+12025551111",
        "condition": "Last resort: drop to the main line if no one is available",
        "mode": "cold"
      }
    ],
    "warmTransferConfig": {
      "holdMessage": "Please hold while I connect you with our support team.",
      "holdMusicEnabled": true,
      "summaryPrompt": "Focus on the customer's main concern and any account details mentioned.",
      "introMessage": "You're now connected. They're up to speed on your request.",
      "continueRecordingAfterTransfer": false
    }
  }'
```

<Note>
  Warm transfer is also available as a node type in [Conversation Flows](/platform/conversation-flows), where you can configure hold and summary settings per-node.
</Note>

### Voicemail Detection

Voicemail Detection automatically identifies when an outbound call reaches an answering machine or voicemail system.

#### When to Use

* Outbound calling campaigns where live conversations are preferred
* Appointment reminders or confirmations
* Sales or follow-up calls
* Any scenario where leaving a message is optional

#### Configuration

1. Navigate to the **Tools** tab

2. Locate **Voicemail Detection** under System Tools

3. Toggle the switch to enable

4. Click **Configure** to set behavior

5. Choose **Voicemail Action**:
   * **Hangup**: Immediately end the call when voicemail is detected (saves costs)
   * **Leave Message**: Speak a pre-recorded message before hanging up

6. If you selected "Leave Message", configure **Voicemail Message**:

```
Hi, this is a message from Acme Corp. We tried reaching you regarding your appointment. Please call us back at 1-800-555-0123. Thank you.
```

7. Click **Save**

<Note>
  Voicemail detection is most effective for outbound calls. For inbound calls, it's typically not needed since customers are calling you.
</Note>

#### How It Works

When an outbound call connects, RevRing analyzes the audio to detect voicemail systems. If detected:

* **Hangup action**: Call ends immediately, marked as "voicemail" in logs
* **Leave message action**: Agent speaks the configured message, then hangs up

Detection accuracy is typically very high but not perfect. Review call logs to monitor detection performance.

### Press Digits (DTMF)

The Press Digits tool allows the agent to send DTMF touch tones during a call. This is useful when navigating IVR (interactive voice response) systems — for example, when the agent needs to press digits to navigate a phone menu during a transferred call or an outbound call to a phone system.

#### When to Use

* Navigating automated phone menus (e.g., "Press 1 for sales, press 2 for support")
* Entering account numbers or PINs via keypad
* Interacting with external IVR systems during outbound calls

#### Configuration

1. Navigate to the **Tools** tab
2. Locate **Press Digits** under System Tools
3. Toggle the switch to enable
4. Optionally set a **Custom Instructions Override** to customize when the agent uses this tool
5. Click **Save**

#### Configuring via API

```bash theme={null}
curl -X PATCH https://api.revring.ai/v1/agents/{agentId} \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "playKeypadTouchToneEnabled": true,
    "playKeypadTouchToneDescriptionOverride": "Use this to press digits when navigating phone menus."
  }'
```

<Note>
  DTMF input is also available as a dedicated node type (`press_digit`) in [Conversation Flows](/platform/conversation-flows), where you can specify which digits to listen for and how long to wait.
</Note>

## Advanced Settings

### Block All Interruptions

By default, callers can interrupt the agent while it's speaking. Enable **Block All Interruptions** to make the agent always finish speaking before listening for input.

#### When to Use

* Delivering important legal disclaimers or disclosures that must be heard in full
* Reading back critical information (order numbers, confirmation codes)
* Playing scripted messages that should not be cut short

#### Configuration

1. Navigate to the **Advanced** tab
2. Toggle **Block All Interruptions** to on
3. Click **Save**

#### Configuring via API

```bash theme={null}
curl -X PATCH https://api.revring.ai/v1/agents/{agentId} \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "disableInterruptions": true
  }'
```

<Note>
  Block All Interruptions applies to all agent speech globally. In [Conversation Flows](/platform/conversation-flows), you can set `blockInterruptions` on individual nodes for more granular control.
</Note>

### Interruption Threshold

The **Interruption Threshold** controls how much speech is required from the caller before the agent treats it as an interruption and stops talking. This is measured in milliseconds.

* **Lower values** (e.g. 100 ms) make the agent very sensitive — even a short utterance will interrupt it.
* **Higher values** (e.g. 2000 ms) make the agent less sensitive — the caller must speak for longer before the agent pauses.
* **Default**: 500 ms

This is useful for tuning the conversational feel. If your agent is being interrupted too easily by background noise or brief acknowledgements (like "uh huh"), increase the threshold. If callers have difficulty getting a word in, lower it.

#### Configuration

1. Navigate to the **Advanced** tab
2. Adjust the **Interruption Threshold** slider (100–2000 ms)
3. Click **Save**

#### Configuring via API

```bash theme={null}
curl -X PATCH https://api.revring.ai/v1/agents/{agentId} \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "interruptionThresholdMs": 750
  }'
```

<Note>
  If **Block All Interruptions** is enabled, the interruption threshold has no effect since all interruptions are disabled.
</Note>

## Custom Tools

Custom tools allow you to extend agent capabilities by integrating with your own systems via webhooks. When the agent invokes a custom tool, RevRing calls your webhook with the tool's arguments and includes the response in the conversation.

### Use Cases

* **CRM lookups**: Fetch customer information during calls
* **Order status**: Check order or shipment status
* **Appointment booking**: Create or modify appointments in your calendar system
* **Payment processing**: Initiate payments or check account balances
* **Inventory checks**: Verify product availability
* **Custom business logic**: Any operation specific to your workflow

### Creating a Custom Tool

1. Navigate to the **Tools** tab
2. Scroll to the **Custom Tools** section
3. Enter a **Friendly Name** for your tool (e.g., "Order Status Checker")
4. Enter your **Webhook URL** (e.g., `https://api.yourcompany.com/tools/check-order`)
5. Click **Add Tool**

The tool will appear in the table below. Click **Edit** to define the tool's schema.

<Note>
  The **Friendly Name** is just a label for the dashboard. The actual function name that the agent uses is defined in the `name` field of your JSON schema (e.g., `check_order_status`).
</Note>

### Defining the Tool Schema

The schema defines what parameters the tool accepts using OpenAI's function calling format:

1. Click **Edit** on your custom tool
2. In the **Schema JSON** field, enter your tool definition:

```json theme={null}
{
  "type": "function",
  "name": "check_order_status",
  "description": "Check the status of a customer's order by order ID",
  "parameters": {
    "type": "object",
    "properties": {
      "order_id": {
        "type": "string",
        "description": "The unique order ID (e.g., ORD-12345)"
      }
    },
    "required": ["order_id"],
    "additionalProperties": false
  }
}
```

3. Toggle **Enabled** to activate the tool
4. Click **Save**

<Tip>
  The `description` fields are critical - they tell the agent when and how to use the tool. Be clear and specific.
</Tip>

### Schema Format Reference

Follow the [OpenAI function calling format](https://platform.openai.com/docs/guides/function-calling#defining-functions):

* **type**: Always `"function"` at the root level (required)
* **name**: Unique identifier for the tool (lowercase, underscores allowed) (required)
* **description**: When the agent should use this tool (required)
* **parameters**: Object defining the tool's input parameters (required)
  * **type**: Always `"object"` for the parameters root (required)
  * **properties**: Each parameter with its type and description (use `{}` for tools with no inputs)
  * **required**: Array of required parameter names (optional)

<Note>
  **For tools without inputs:** You must still include the `parameters` object with `type: "object"` and empty `properties`:

  ```json theme={null}
  {
    "type": "function",
    "name": "get_current_weather",
    "description": "Get the current weather",
    "parameters": {
      "type": "object",
      "properties": {}
    }
  }
  ```
</Note>

### Advanced Webhook Settings

By default, RevRing sends a `POST` request with a JSON body to your webhook URL when a tool is invoked. You can customize this behavior per tool:

| Setting                   | Description                                                                                                                      | Default |
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | ------- |
| **HTTP Method**           | The HTTP method used to call your webhook (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`)                                              | `POST`  |
| **Headers**               | Custom HTTP headers to include in the request (e.g., `Authorization: Bearer token123`)                                           | None    |
| **Query Parameters**      | Custom query parameters appended to the webhook URL (e.g., `source=revring`)                                                     | None    |
| **Send Raw Request Body** | When enabled, sends the tool arguments directly as the request body instead of the default `{ callId, tool, arguments }` wrapper | Off     |

These settings are configured per-tool in the dashboard or via the API:

```bash theme={null}
curl -X POST https://api.revring.ai/v1/agents/{agentId}/custom-tools \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Check Order",
    "webhookUrl": "https://api.yourcompany.com/tools/check-order",
    "httpMethod": "POST",
    "headers": [
      { "key": "Authorization", "value": "Bearer your-token" }
    ],
    "queryParams": [
      { "key": "source", "value": "revring" }
    ],
    "sendRawRequestBody": false,
    "enabled": true,
    "schema": {
      "type": "function",
      "name": "check_order_status",
      "description": "Check order status by order ID",
      "parameters": {
        "type": "object",
        "properties": {
          "order_id": { "type": "string", "description": "The order ID" }
        },
        "required": ["order_id"]
      }
    }
  }'
```

### Webhook Request Format

When the agent invokes your custom tool, RevRing sends a request to your webhook URL.

**Default request body (when Send Raw Request Body is off):**

```json theme={null}
{
  "callId": "dc582fd6-4e5c-4860-9ced-abc7390e62a9",
  "tool": "check_order_status",
  "arguments": {
    "order_id": "ORD-12345"
  }
}
```

**Raw request body (when Send Raw Request Body is on):**

```json theme={null}
{
  "order_id": "ORD-12345"
}
```

<Note>
  Custom tools also run on text channels — [web widget chat](/platform/web-widget) and [SMS](/platform/two-way-messaging). Text invocations use the same request format, with `callId` set to `null` and two extra fields — `conversationId` and `channel` (`"web_chat"` or `"sms"`) — identifying the message thread instead of a call.
</Note>

**Response Examples:**

You can return either JSON or plain text:

```json theme={null}
{
  "status": "out_for_delivery",
  "expected_delivery": "2025-11-24T17:00:00Z",
  "tracking_number": "1Z999AA10123456784"
}
```

Or:

```
Order ORD-12345 is currently out for delivery. Expected delivery today by 5 PM.
```

The agent will receive the response and incorporate it into the conversation naturally.

### Response Format

Your webhook should return:

* **200 OK** status code
* JSON object or plain text response body
* Response within 8 seconds (recommended: under 3 seconds for best user experience)

**JSON Response Example:**

```json theme={null}
{
  "appointments": [
    {
      "date": "2025-11-25",
      "time": "14:00",
      "type": "checkup"
    }
  ],
  "total_count": 3
}
```

**Plain Text Response Example:**

```
Customer has 3 active appointments. Next appointment is tomorrow at 2 PM.
```

The agent will interpret the response and communicate the information to the caller naturally.

### Best Practices for Custom Tools

#### Clear Descriptions

The agent uses descriptions to decide when to invoke tools. Be specific:

**Good:**

```
Check the status of a customer's order by order ID. Use this when the customer asks about their order, shipment, or delivery status.
```

**Bad:**

```
Check order
```

#### Error Handling

Handle errors gracefully in your webhook. You can return structured error data or error messages:

```json theme={null}
{
  "error": "order_not_found",
  "message": "Order number not found in system"
}
```

Or plain text:

```
I couldn't find that order number in our system. Could you verify the order number?
```

The agent will communicate the error to the caller appropriately.

#### Performance

* Keep webhook response times under 3 seconds
* Implement timeouts and retries in your webhook code
* Cache frequently accessed data when possible
* Use async processing for complex operations (return immediately with a status message)

#### Security

* Validate requests are coming from RevRing (contact support for HMAC signing setup)
* Sanitize and validate all input parameters
* Use HTTPS for all webhook URLs
* Implement rate limiting to prevent abuse

### Testing Custom Tools

1. Create a simple test tool that returns static data
2. Use the **test panel** to make a call
3. During the call, prompt the agent to use the tool:
   * "Can you check order ORD-12345 for me?"
4. Review the transcript to see:
   * Tool invocation with arguments
   * Your webhook's response
   * How the agent incorporated the result into conversation

### Viewing Tool Invocations

All tool invocations appear in call transcripts with detailed information:

* **Tool name**: Which tool was invoked
* **Arguments**: What parameters were passed
* **Status**: Success (ok) or error
* **Response**: What your webhook returned

Navigate to [Call Logs](https://dashboard.revring.ai/app/calls), select a call, and review the transcript pane.

## Tool Limitations

### System Tool Constraints

* **End Call**: Once invoked, the call ends immediately - the agent cannot continue conversation
* **Transfer**: After transfer, the agent disconnects - the call continues with the transfer destination
* **Voicemail Detection**: Only works on outbound calls, not inbound calls

### Custom Tool Constraints

* **Response time**: 8 second timeout - webhooks must respond within this window
* **Concurrent invocations**: Agents invoke tools sequentially, not in parallel

## Managing Tools

### Editing Tools

To modify a custom tool:

1. Navigate to the **Tools** tab
2. Click **Edit** on the tool in the table
3. Update friendly name, webhook URL, schema, or enabled status
4. Click **Save**

Changes take effect immediately for new calls.

### Deleting Tools

To remove a custom tool:

1. Navigate to the **Tools** tab
2. Click **Delete** on the tool in the table
3. Confirm the deletion

<Warning>
  Deleting a tool that's actively referenced in your agent's behavior may cause unexpected results. Update your prompt to remove references to deleted tools.
</Warning>

### Disabling Tools Temporarily

Instead of deleting, you can disable tools:

1. Click **Edit** on the tool
2. Toggle **Enabled** to off
3. Click **Save**

The agent will not have access to disabled tools, but the configuration is preserved for future re-enabling.

## Advanced Tool Patterns

### Chaining Tools

Agents can invoke multiple tools in sequence to accomplish complex tasks:

1. Customer asks: "What's my balance and when is my next payment due?"
2. Agent invokes `get_account_balance` → receives balance
3. Agent invokes `get_next_payment_date` → receives date
4. Agent combines both results in response

Design tools to be focused and composable rather than monolithic.

### Conditional Tool Usage

Guide the agent to use tools conditionally based on conversation context:

```
Use the transfer_to_billing tool only when:
- Customer has billing questions you cannot answer
- Customer disputes a charge
- Customer wants to discuss payment plans

Do NOT transfer for simple balance inquiries - use the check_balance tool instead.
```

### Tool Results in Follow-Up

Agents can reference previous tool results later in the conversation:

> Agent: "I checked your order ORD-12345, and it's out for delivery today."
>
> Customer: "Great! And what about my other order?"
>
> Agent: "Let me check that for you..." *\[invokes tool again with new order ID]*

## Troubleshooting

<AccordionGroup>
  <Accordion title="Custom tool not being invoked">
    * Verify the tool is enabled (toggle is on)
    * Check that the description clearly indicates when to use the tool
    * Ensure your prompt doesn't contradict or override the tool's purpose
    * Test by explicitly asking the agent to use the tool during a test call
    * Review the schema - overly complex parameters may confuse the agent
  </Accordion>

  <Accordion title="Webhook not receiving requests">
    * Confirm the webhook URL is correct and publicly accessible
    * Check that your server is running and responding to POST requests
    * Test the endpoint independently with curl or Postman
    * Review your server logs for incoming requests
  </Accordion>

  <Accordion title="Tool returns error in transcript">
    * Verify webhook responds within 8 seconds
    * Ensure response is valid JSON or plain text
    * Check HTTP status code (should be 200)
    * Review your webhook logs for errors or exceptions
    * Test the webhook endpoint independently with sample data
  </Accordion>

  <Accordion title="Agent misuses the tool">
    * Refine the tool's description to be more specific about usage
    * Update your prompt to provide clearer guidance on when to use tools
    * Adjust parameter descriptions to clarify expected formats
    * Consider splitting complex tools into simpler, focused tools
  </Accordion>

  <Accordion title="Transfer doesn't work">
    * Verify the destination number is in valid E.164 format
    * Ensure your SIP trunk supports call transfers
    * Check that the destination number is reachable
    * Review call logs for specific transfer error messages
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Webhooks" icon="webhook" href="/platform/webhooks">
    Learn about pre-call and post-call webhooks
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/agents/list-custom-tools">
    Manage custom tools programmatically via API
  </Card>

  <Card title="Inbound Calls" icon="arrow-left-to-line" href="/platform/inbound">
    Configure agents for handling inbound calls
  </Card>

  <Card title="Outbound Calls" icon="arrow-right-to-line" href="/platform/outbound">
    Send outbound calls with your agents
  </Card>
</CardGroup>
