Skip to main content

Overview

Custom API actions let your AI agents integrate with external systems during conversations. Your agents can retrieve customer data, update CRM records, check inventory, create tickets, and execute business logic - all in real-time while talking to customers.
Create Custom Action modal showing Action Name field 'Fetch Customer Data', Description field explaining action usage, four tabs (Endpoint, Authentication, Parameters, Variables) with Endpoint tab active, HTTP Method options (GET, POST, PUT, PATCH, DELETE) with POST selected, Endpoint URL field with placeholder, and Cancel/Create Action buttons
Create Custom Action modal showing Action Name field 'Fetch Customer Data', Description field explaining action usage, four tabs (Endpoint, Authentication, Parameters, Variables) with Endpoint tab active, HTTP Method options (GET, POST, PUT, PATCH, DELETE) with POST selected, Endpoint URL field with placeholder, and Cancel/Create Action buttons
How it works:
  1. Configure the API endpoint - Set up HTTP method, URL, authentication, headers, and request body
  2. Define variables - Specify what information the agent needs to collect before calling the API
  3. Agent uses it - During conversation, agent collects the variables and calls your API
  4. API responds - Your system returns data that the agent uses to continue the conversation
Custom actions execute synchronously during conversations. For operations that don’t need immediate responses (logging, analytics, post-call processing), use Webhooks instead.

Example Flow

Customer: "What's the status of my order?"

Agent: (collects order number from customer)

[Agent calls API]
→ GET https://api.company.com/orders/12345
← { "status": "shipped", "tracking": "1Z999AA10123456789" }

Agent: "Your order has shipped! Your tracking number is
       1Z999AA10123456789 and it should arrive by Friday."
Security: Verify customer identity before exposing sensitive data. Always authenticate customers before calling APIs that return personal information, order details, account data, or other sensitive information.

Secure Example with Verification

For sensitive data lookups, verify customer identity first:
Customer: "What's the status of my order?"

Agent: "I'd be happy to check that. For security, I need to verify
       your identity first. What's your customer number?"
Customer: "12345"

Agent: "And for verification, what's your phone PIN?"
Customer: "5678"

[Agent calls verification API first]
→ POST https://api.company.com/auth/verify
  Body: {"customer_id": "12345", "phone_pin": "5678"}
← { "verified": true, "customer_name": "John Smith" }

[Only if verified, then call order lookup]
→ GET https://api.company.com/customers/12345/orders
← { "orders": [{"id": "ORD-789", "status": "shipped", ...}] }

Agent: "Thank you, John. I've verified your identity. Your order
       ORD-789 has shipped and should arrive by Friday."
Two-action pattern:
  1. First action: “Verify Customer” - authenticates using customer ID + PIN/password
  2. Second action: “Lookup Order” - only executed if verification succeeds
In your agent instructions:
Before looking up any sensitive customer information:

1. Collect customer ID and phone PIN
2. Use 'Verify Customer' action
3. If verification fails:
   - "I'm unable to verify that information. For security,
      I'll need to transfer you to our verification team."
   - Transfer to human agent
4. If verification succeeds:
   - Proceed with 'Lookup Order' or other sensitive actions

Creating a Custom Action

1

Navigate to Actions

Go to your agent → Abilities → ActionsAdd ActionCustom API
2

Configure Basic Info

  • Name: Descriptive name (e.g., “Lookup Order Status”)
  • Description: When to use it (10-200 characters)
3

Configure Endpoint

See Endpoint Configuration below
4

Set Up Authentication

See Authentication Methods below
5

Add Variables

Define what information the agent needs to collect (see Variables section)
6

Test

Save and test with your agent

Configuration

Endpoint Tab

HTTP Method (Required)
  • GET - Retrieve data
  • POST - Create records
  • PUT - Replace entire records
  • PATCH - Update specific fields
  • DELETE - Remove records
Endpoint URL (Required)
  • Full API URL: https://api.company.com/customers
  • Supports template variables: https://api.company.com/orders/{{order_id}}
  • Auto-prepends https:// if no protocol specified

Authentication Tab

Choose authentication type:
No authentication requiredUse for:
  • Public APIs
  • Internal endpoints on private network
Most common for modern APIsConfiguration:
  • Token: Your API token/JWT
Sends:
Authorization: Bearer {your_token}
Use for:
  • OAuth 2.0 access tokens
  • JWT authentication
  • Modern REST APIs
Username/password authenticationConfiguration:
  • Username: API username
  • Password: API password (masked with bullets when editing)
Sends:
Authorization: Basic {base64(username:password)}
Use for:
  • Legacy APIs
  • Simple authentication
Custom header-based authConfiguration:
  • Header Name: e.g., X-API-Key
  • Header Value: Your API key (masked when editing)
Sends:
X-API-Key: {your_api_key}
Use for:
  • API key authentication
  • Custom auth schemes
Credentials in request bodyConfiguration:
  • Parameter Name: e.g., api_key
  • Parameter Value: Your credential (masked when editing)
Sends in body:
{
  "api_key": "{your_key}",
  ...other params
}
Use for:
  • Non-standard auth schemes
  • Login endpoints
Credentials are encrypted in the database and masked in the UI. When editing existing actions, unchanged credentials are preserved - you only need to re-enter them if changing.

Parameters Tab

Headers
  • Add custom HTTP headers (key-value pairs)
  • Example: Content-Type: application/json
Query Parameters (GET requests)
  • Add URL query parameters (key-value pairs)
  • Example: include=orders&limit=100
Request Body (POST/PUT/PATCH)
  • JSON textarea with Monaco-style font
  • Supports template variables: {{variable_name}}
  • Validates JSON structure while allowing variable placeholders
Example:
{
  "customer_id": "{{customer_id}}",
  "status": "contacted",
  "timestamp": "{{current_datetime}}"
}

Variables Tab

This is the most important part. Variables define what information your agent needs to collect before calling the API. Each variable creates a function parameter that the LLM sees and collects during conversation. Variable Fields:
  • Name: Variable name (e.g., order_number, customer_email)
  • Type: string, integer, float, boolean, date, email, phone
  • Description: What this variable is for (helps the LLM understand)
  • Example: Example value (guides the LLM)
  • Required: Toggle - if true, LLM must collect before calling API
  • Default Value: Used if not required and not provided
Example Variable:
Name: order_number
Type: string
Description: Customer's order number
Example: ORD-12345
Required: Yes
The LLM sees this as a function parameter and knows to ask the customer for their order number before calling the API.

Using in Instructions

Reference the action by name and explain when to use it:
When a customer asks about their order status:

1. Ask for their order number
2. Use the 'Lookup Order Status' action
3. Share the status information with them

If the action returns an error:
- 404: "I don't see an order with that number"
- 500: "I'm having trouble accessing the system right now"
- Offer to have someone call them back

Variable Collection

The agent automatically collects required variables before calling the API:
# Your action has a variable: order_number (required, string)

Customer: "What's my order status?"
Agent: "I'd be happy to check that. What's your order number?"
Customer: "ORD-12345"
Agent: [Calls API with order_number="ORD-12345"]

Using Optional Variables

# Variable: email (not required, default: "not-provided@example.com")

Agent collects email if customer provides it, otherwise uses default

Template Variables

Use {{variable_name}} syntax in URLs, headers, query params, and request body.

Action Variables

Variables you defined in the Variables tab:
URL: https://api.company.com/orders/{{order_number}}
Body: {"email": "{{customer_email}}"}

Context Variables

Available automatically from contact record and call context: Contact Information:
{{contact.first_name}}
{{contact.last_name}}
{{contact.email}}
{{contact.phone_number}}
{{contact.id}}
Agent & Call Context:
{{agent_number}}
{{agent_name}}
{{agent_id}}
{{direction}}          # inbound/outbound
{{medium}}            # phone/web
{{current_datetime}}  # ISO 8601 timestamp

Type Conversion

Variables are automatically converted to their defined types:
  • integer → number in JSON
  • float → decimal in JSON
  • boolean → true/false in JSON
  • string → quoted string in JSON

Testing

1

Test Endpoint Independently

Use Postman or cURL to verify:
  • Endpoint is reachable
  • Authentication works
  • Request format is correct
  • Response is as expected
2

Start with Static Values

Configure action with hardcoded values first (no variables)Verify basic functionality before adding complexity
3

Add Variables

Replace hardcoded values with variablesTest with contact record that has required fields
4

Test in Agent

  1. Start web call
  2. Trigger the action through conversation
  3. Verify agent collects variables correctly
  4. Check API is called with correct data
  5. Confirm agent uses response appropriately
5

Test Error Scenarios

  • API returns 404 (not found)
  • API returns 500 (server error)
  • Authentication fails (401)
  • Missing required variables

Troubleshooting

Cause: Invalid credentials or wrong auth typeSolution:
  • Verify credentials are correct
  • Check authentication type matches API requirements
  • Test with Postman using same credentials
  • Verify token hasn’t expired
Cause: Incorrect URL or resource doesn’t existSolution:
  • Verify endpoint URL is correct
  • Check template variables populate correctly
  • Test with static values first
Cause: Variables not configured or unclear descriptionsSolution:
  • Verify variables are defined in Variables tab
  • Add clear descriptions and examples
  • Set required=true for essential variables
  • Reference action by exact name in instructions
Cause: Incorrect syntax or variable doesn’t existSolution:
  • Use exact syntax: {{variable_name}}
  • Verify variable is defined in Variables tab
  • Check contact record has field populated
  • Set default value in Variables tab for optional variables
Cause: API responding slowly (>2 minutes)Solution:
  • Optimize API response time
  • Consider using webhooks for slow operations
  • Cache frequently accessed data
Cause: API returning non-JSON or malformed JSONSolution:
  • Verify API returns valid JSON
  • Check Content-Type header in response
  • Test response with JSON validator

Security Best Practices

Always use HTTPS endpoints to encrypt data in transithttps://api.company.com/endpointhttp://api.company.com/endpoint
  • Never hardcode credentials in URLs
  • Use authentication configuration
  • Rotate API keys regularly
  • Use separate keys for testing vs production
  • Revoke compromised credentials immediately
  • Grant minimum necessary API permissions
  • Use read-only keys for lookup actions
  • Restrict write permissions to specific endpoints
  • Monitor for unusual activity
Your API should validate all inputs:
  • Check for injection attempts
  • Validate data types and formats
  • Limit string lengths
  • Use parameterized queries

Real-World Examples

Scenario: Look up customer in SalesforceConfiguration:
  • Method: GET
  • URL: https://api.salesforce.com/customers/{{customer_id}}
  • Auth: Bearer token
  • Variable: customer_id (string, required)
Agent Instructions:
When asked about account details:
1. Ask for customer ID
2. Use 'Lookup Customer' action
3. Share account information from response
Scenario: Create ticket in ZendeskConfiguration:
  • Method: POST
  • URL: https://company.zendesk.com/api/v2/tickets
  • Auth: Basic (email/token)
  • Variables: issue_description (string), priority_level (string)
  • Body:
{
  "ticket": {
    "subject": "Call with {{contact.first_name}}",
    "description": "{{issue_description}}",
    "priority": "{{priority_level}}"
  }
}
Agent Instructions:
When customer has an issue I can't resolve:
1. Collect detailed issue description
2. Determine priority (normal, high, urgent)
3. Use 'Create Ticket' action
4. Give customer the ticket number
Scenario: Check product availabilityConfiguration:
  • Method: GET
  • URL: https://inventory.company.com/products/{{sku}}/availability
  • Auth: Header (X-API-Key)
  • Variable: sku (string, required, example: “PROD-12345”)
Agent Instructions:
When asked about product availability:
1. Get product SKU from customer
2. Use 'Check Inventory' action
3. If in stock: confirm availability
4. If out of stock: provide expected restock date

Next Steps