|
| 1 | +--- |
| 2 | +title: Code Tool |
| 3 | +subtitle: Execute custom TypeScript code directly within your assistant without setting up a server. |
| 4 | +slug: tools/code-tool |
| 5 | +--- |
| 6 | + |
| 7 | +The Code Tool allows you to write and execute custom TypeScript code that runs when your assistant needs to perform a specific action. Unlike custom function tools that require you to host a server, code tools run directly on Vapi's infrastructure. |
| 8 | + |
| 9 | +## When to Use Code Tools |
| 10 | + |
| 11 | +Code tools are ideal when you need to: |
| 12 | +- Transform or process data during a conversation |
| 13 | +- Make HTTP requests to external APIs |
| 14 | +- Perform calculations or business logic |
| 15 | +- Avoid the overhead of setting up and maintaining a webhook server |
| 16 | + |
| 17 | +## Creating a Code Tool |
| 18 | + |
| 19 | +### Step 1: Navigate to the Tools Section |
| 20 | + |
| 21 | +1. Open your [Vapi Dashboard](https://dashboard.vapi.ai) |
| 22 | +2. Click **Tools** in the left sidebar |
| 23 | +3. Click **Create Tool** and select **Code** |
| 24 | + |
| 25 | +### Step 2: Configure Your Code Tool |
| 26 | + |
| 27 | +The dashboard provides a visual interface to configure your code tool: |
| 28 | + |
| 29 | +1. **Tool Name**: A descriptive identifier (e.g., `get_customer_data`) |
| 30 | +2. **Description**: Explain what your tool does - this helps the AI understand when to use it |
| 31 | +3. **TypeScript Code**: Write the code that will execute when the tool is called |
| 32 | +4. **Parameters**: Define the input parameters your code expects |
| 33 | +5. **Environment Variables**: Store sensitive values like API keys securely |
| 34 | + |
| 35 | +### Step 3: Write Your Code |
| 36 | + |
| 37 | +Your code has access to two objects: |
| 38 | +- **`args`**: Contains the parameters passed by the assistant |
| 39 | +- **`env`**: Contains your environment variables |
| 40 | + |
| 41 | +```typescript |
| 42 | +// Access parameters from the assistant |
| 43 | +const { customerId, orderType } = args; |
| 44 | + |
| 45 | +// Access secure environment variables |
| 46 | +const { API_KEY, API_URL } = env; |
| 47 | + |
| 48 | +// Make HTTP requests to external services |
| 49 | +const response = await fetch(`${API_URL}/customers/${customerId}`, { |
| 50 | + headers: { |
| 51 | + 'Authorization': `Bearer ${API_KEY}`, |
| 52 | + 'Content-Type': 'application/json' |
| 53 | + } |
| 54 | +}); |
| 55 | + |
| 56 | +const customer = await response.json(); |
| 57 | + |
| 58 | +// Return data to the assistant |
| 59 | +return { |
| 60 | + name: customer.name, |
| 61 | + email: customer.email, |
| 62 | + memberSince: customer.createdAt |
| 63 | +}; |
| 64 | +``` |
| 65 | + |
| 66 | +<Note> |
| 67 | +Your code runs in an isolated environment with a configurable timeout (default: 10 seconds, max: 60 seconds). |
| 68 | +</Note> |
| 69 | + |
| 70 | +## Example: Customer Lookup Tool |
| 71 | + |
| 72 | +Let's create a tool that looks up customer information: |
| 73 | + |
| 74 | +### Configuration |
| 75 | + |
| 76 | +| Field | Value | |
| 77 | +|-------|-------| |
| 78 | +| Tool Name | `get_customer` | |
| 79 | +| Description | Retrieves customer information by their ID | |
| 80 | + |
| 81 | +### Parameters |
| 82 | + |
| 83 | +| Name | Type | Required | Description | |
| 84 | +|------|------|----------|-------------| |
| 85 | +| customerId | string | Yes | The unique customer identifier | |
| 86 | + |
| 87 | +### Environment Variables |
| 88 | + |
| 89 | +| Name | Value | |
| 90 | +|------|-------| |
| 91 | +| API_KEY | Your API key | |
| 92 | +| API_BASE_URL | https://api.yourservice.com | |
| 93 | + |
| 94 | +### Code |
| 95 | + |
| 96 | +```typescript |
| 97 | +const { customerId } = args; |
| 98 | +const { API_KEY, API_BASE_URL } = env; |
| 99 | + |
| 100 | +const response = await fetch(`${API_BASE_URL}/customers/${customerId}`, { |
| 101 | + headers: { |
| 102 | + 'Authorization': `Bearer ${API_KEY}` |
| 103 | + } |
| 104 | +}); |
| 105 | + |
| 106 | +if (!response.ok) { |
| 107 | + return { error: 'Customer not found' }; |
| 108 | +} |
| 109 | + |
| 110 | +const customer = await response.json(); |
| 111 | + |
| 112 | +return { |
| 113 | + name: customer.name, |
| 114 | + email: customer.email, |
| 115 | + plan: customer.subscription.plan, |
| 116 | + status: customer.status |
| 117 | +}; |
| 118 | +``` |
| 119 | + |
| 120 | +## Example: Order Processing Tool |
| 121 | + |
| 122 | +A more complex example that processes an order: |
| 123 | + |
| 124 | +### Parameters |
| 125 | + |
| 126 | +| Name | Type | Required | Description | |
| 127 | +|------|------|----------|-------------| |
| 128 | +| items | array | Yes | Array of item objects with id and quantity | |
| 129 | +| customerId | string | Yes | The customer placing the order | |
| 130 | +| shippingAddress | string | No | Delivery address | |
| 131 | + |
| 132 | +### Code |
| 133 | + |
| 134 | +```typescript |
| 135 | +const { items, customerId, shippingAddress } = args; |
| 136 | +const { ORDER_API_KEY, ORDER_API_URL } = env; |
| 137 | + |
| 138 | +// Calculate total |
| 139 | +let total = 0; |
| 140 | +const itemDetails = []; |
| 141 | + |
| 142 | +for (const item of items) { |
| 143 | + const priceResponse = await fetch(`${ORDER_API_URL}/products/${item.id}`); |
| 144 | + const product = await priceResponse.json(); |
| 145 | + |
| 146 | + const itemTotal = product.price * item.quantity; |
| 147 | + total += itemTotal; |
| 148 | + |
| 149 | + itemDetails.push({ |
| 150 | + name: product.name, |
| 151 | + quantity: item.quantity, |
| 152 | + price: product.price, |
| 153 | + subtotal: itemTotal |
| 154 | + }); |
| 155 | +} |
| 156 | + |
| 157 | +// Create the order |
| 158 | +const orderResponse = await fetch(`${ORDER_API_URL}/orders`, { |
| 159 | + method: 'POST', |
| 160 | + headers: { |
| 161 | + 'Authorization': `Bearer ${ORDER_API_KEY}`, |
| 162 | + 'Content-Type': 'application/json' |
| 163 | + }, |
| 164 | + body: JSON.stringify({ |
| 165 | + customerId, |
| 166 | + items: itemDetails, |
| 167 | + total, |
| 168 | + shippingAddress |
| 169 | + }) |
| 170 | +}); |
| 171 | + |
| 172 | +const order = await orderResponse.json(); |
| 173 | + |
| 174 | +return { |
| 175 | + orderId: order.id, |
| 176 | + total: `$${total.toFixed(2)}`, |
| 177 | + estimatedDelivery: order.estimatedDelivery, |
| 178 | + items: itemDetails.map(i => `${i.quantity}x ${i.name}`) |
| 179 | +}; |
| 180 | +``` |
| 181 | + |
| 182 | +## Using Code Tools in Assistants |
| 183 | + |
| 184 | +Once created, add your code tool to any assistant: |
| 185 | + |
| 186 | +### In the Dashboard |
| 187 | + |
| 188 | +1. Go to **Assistants** → Select your assistant |
| 189 | +2. Navigate to the **Tools** tab |
| 190 | +3. Click **Add Tool** and select your code tool |
| 191 | +4. Save your assistant configuration |
| 192 | + |
| 193 | +### Via API |
| 194 | + |
| 195 | +```bash |
| 196 | +curl --location --request PATCH 'https://api.vapi.ai/assistant/ASSISTANT_ID' \ |
| 197 | +--header 'Authorization: Bearer <YOUR_API_KEY>' \ |
| 198 | +--header 'Content-Type: application/json' \ |
| 199 | +--data '{ |
| 200 | + "model": { |
| 201 | + "toolIds": ["your-code-tool-id"] |
| 202 | + } |
| 203 | +}' |
| 204 | +``` |
| 205 | + |
| 206 | +## Creating Code Tools via API |
| 207 | + |
| 208 | +You can also create code tools programmatically: |
| 209 | + |
| 210 | +```bash |
| 211 | +curl --location 'https://api.vapi.ai/tool' \ |
| 212 | +--header 'Content-Type: application/json' \ |
| 213 | +--header 'Authorization: Bearer <YOUR_API_KEY>' \ |
| 214 | +--data '{ |
| 215 | + "type": "code", |
| 216 | + "name": "get_customer", |
| 217 | + "description": "Retrieves customer information by their ID", |
| 218 | + "code": "const { customerId } = args;\nconst { API_KEY } = env;\n\nconst response = await fetch(`https://api.example.com/customers/${customerId}`, {\n headers: { \"Authorization\": `Bearer ${API_KEY}` }\n});\n\nreturn await response.json();", |
| 219 | + "parameters": { |
| 220 | + "type": "object", |
| 221 | + "properties": { |
| 222 | + "customerId": { |
| 223 | + "type": "string", |
| 224 | + "description": "The unique customer identifier" |
| 225 | + } |
| 226 | + }, |
| 227 | + "required": ["customerId"] |
| 228 | + }, |
| 229 | + "environmentVariables": [ |
| 230 | + { |
| 231 | + "name": "API_KEY", |
| 232 | + "value": "your-api-key-here" |
| 233 | + } |
| 234 | + ] |
| 235 | +}' |
| 236 | +``` |
| 237 | + |
| 238 | +## Best Practices |
| 239 | + |
| 240 | +### Security |
| 241 | +- Store sensitive values (API keys, secrets) in **Environment Variables**, not in your code |
| 242 | +- Environment variable values support Liquid templates to reference call variables |
| 243 | + |
| 244 | +### Performance |
| 245 | +- Keep code execution under the timeout limit |
| 246 | +- Use efficient API calls and avoid unnecessary loops |
| 247 | +- Consider caching strategies for repeated lookups |
| 248 | + |
| 249 | +### Error Handling |
| 250 | +- Always handle potential errors from API calls |
| 251 | +- Return meaningful error messages that help the assistant respond appropriately |
| 252 | + |
| 253 | +```typescript |
| 254 | +const { customerId } = args; |
| 255 | + |
| 256 | +try { |
| 257 | + const response = await fetch(`${env.API_URL}/customers/${customerId}`); |
| 258 | + |
| 259 | + if (!response.ok) { |
| 260 | + return { |
| 261 | + error: true, |
| 262 | + message: `Customer ${customerId} not found` |
| 263 | + }; |
| 264 | + } |
| 265 | + |
| 266 | + return await response.json(); |
| 267 | +} catch (error) { |
| 268 | + return { |
| 269 | + error: true, |
| 270 | + message: 'Unable to reach customer service' |
| 271 | + }; |
| 272 | +} |
| 273 | +``` |
| 274 | + |
| 275 | +### Return Values |
| 276 | +- Return structured data that the assistant can easily interpret |
| 277 | +- Include relevant information the assistant needs to continue the conversation |
| 278 | + |
| 279 | +## Limitations |
| 280 | + |
| 281 | +- **Timeout**: Maximum execution time is 60 seconds (default: 10 seconds) |
| 282 | +- **No file system access**: Code runs in an isolated environment without file access |
| 283 | +- **Memory**: Code runs with limited memory allocation |
| 284 | +- **Network**: Only outbound HTTP/HTTPS requests are supported |
| 285 | + |
| 286 | +## Code Tool vs Custom Function Tool |
| 287 | + |
| 288 | +| Feature | Code Tool | Custom Function Tool | |
| 289 | +|---------|-----------|---------------------| |
| 290 | +| Server Required | No | Yes | |
| 291 | +| Language | TypeScript | Any | |
| 292 | +| Setup Complexity | Low | Higher | |
| 293 | +| Customization | Moderate | Full control | |
| 294 | +| Secrets Management | Environment Variables | Your server | |
| 295 | +| Best For | Quick integrations, API calls | Complex logic, existing infrastructure | |
| 296 | + |
| 297 | +Choose **Code Tools** when you want to quickly add functionality without managing infrastructure. Choose **Custom Function Tools** when you need full control over the execution environment or have existing server infrastructure. |
| 298 | + |
0 commit comments