Vapi and GoHighLevel Info
Vapi and GoHighLevel Info
Assistants Tools
Code Tool
Execute custom TypeScript code directly within your assistant without setting up a server.
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.
2. Description: Explain what your tool does - this helps the AI understand when to use it
3. TypeScript Code: Write the code that will execute when the tool is called
Your code runs in an isolated environment with a configurable timeout (default: 10 seconds, max: 60
seconds).
Example: Customer Lookup Tool
Configuration
Field Value
Parameters
Environment Variables
Name Value
API_BASE_URL [Link]
Code
Parameters
Code
In the Dashboard
Via API
Best Practices
Security
⦁ Store sensitive values (API keys, secrets) in Environment Variables, not in your code
Performance
Error Handling
⦁ Return meaningful error messages that help the assistant respond appropriately
Return Values
⦁ Return structured data that the assistant can easily interpret
Limitations
⦁ No file system access: Code runs in an isolated environment without file access
Best For Quick integrations, API calls Complex logic, existing infrastructure
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.
Built with
Marketplace Modules Workflow Actions and Triggers Marketplace Workflow Actions
Creating a Marketplace
Workflow Action
Marketplace Workflow Actions are the customizable workflow actions managed in Marketplace. You
will be able to create custom actions to push or pull data from your application/API in a workflow
using customized fields and API endpoint.
Typical use-cases
Scenario Example
Custom action param Block users from entering Handlebar syntax in plain text
Constants
Load options by adding custom Label-Value constants
Internal Reference
Load options from HighLevel Internal Modules
Headers
Add headers as per your requirement
{
"options": [
{ "label": "Afghanistan", "value": "AF" },
{ "label": "Åland Islands", "value": "AX" },
{ "label": "Albania", "value": "AL" },
{ "label": "Algeria", "value": "DZ" },
{ "label": "American Samoa", "value": "AS" }
]
}
Headers
Add headers as per your requirement
Sample Payload:
{
"data": {
"name": "John Doe",
"age": "29",
"gender": "male",
"hobbies": ["sports", "music"],
"address": "My Address",
"country": "US",
"profileType": "public",
"dataShare": true,
"tems": true
},
"extras": {
"locationId": "xyz",
"contactId": "abc",
"workflowId": "def"
},
"meta": {
"key": "custom_action_key",
"version": "1.0"
}
}
{
"inputs": [
{
"section": "Personal Info",
"fields": [
{ "field": "name", "title": "Name", "fieldType": "string", "required":
true },
{ "field": "age", "title": "Age", "fieldType": "numerical", "required":
true },
{ "field": "gender", "title": "Gender", "fieldType": "select",
"required": true,
"options": [
{ "label": "Male", "value": "male" },
{ "label": "Female", "value": "female" }
]
}
]
},
{
"section": "Location Info",
"fields": [
{ "field": "village", "title": "Village", "fieldType": "string",
"required": true },
{ "field": "city", "title": "City", "fieldType": "string", "required":
true },
{ "field": "fullAddress", "title": "Your Full Address", "fieldType":
"textarea", "required": true }
]
}
]
}
Sample structure for each Field Types
String
Numeric
Textarea
Select
{
"field": "gender",
"title": "Gender",
"fieldType": "select",
"required": true,
"options": [
{ "label": "Male", "value": "male" },
{ "label": "Female", "value": "female" }
]
}
Multiple Select
{
"field": "hobbies",
"title": "Hobbies",
"fieldType": "multiselect",
"required": true,
"options": [
{ "label": "Sport", "value": "sport" },
{ "label": "Music", "value": "music" }
]
}
Radio
{
"field": "profileType",
"title": "Profile Type",
"fieldType": "radio",
"required": true,
"options": [
{ "label": "Public", "value": "public" },
{ "label": "Private", "value": "private" }
]
}
Toggle
Checkbox
Arrow Function
Write custom arrow functions that receive the input value and return true or false based on
whether the validation passes or fails.
For every validation rule, a custom error message must be provided to display meaningful feedback
when validation fails.
Multi-branch
The Multi-Branch Feature enables the creation of branches that can dynamically adjust based on
various predefined conditions. By allowing multiple branches within a workflow, each contact can be
directed down the appropriate path based on their interactions or status.
Branch Section: Defines the name or identifier for the specific branch section.
Branch Section Description: Provides a brief description or details about the branch section.
Branch Name Label: Specifies the label that will be displayed for the branch name.
Branch Name Helptext: Offers additional information related to the branch name.
Delete Branch Title: Sets the title or label used when deleting a branch.
Delete Branch Description: Describes when a branch is deleted.
Options:
Allow New Branches: Enables users to add new branches within the action.
Is Predefined Branches Editable: Allows users to edit predefined branches within the action.
Show Branches Section: Displays the branch section details to the user.
Disabled Allow new branch
Action Execution
Allows you to choose between an API or a custom code.
API
URL (POST)
Enter your API endpoint URL. When this action is executed data is sent to this API endpoint via POST
method.
Headers
Add required header data that has to be included while sending data to the API endpoint
Sample Payload:
{
"data": {
"name": "John Doe",
"age": "29",
"gender": "male",
"hobbies": ["sports", "music"],
"address": "My Address",
"country": "US",
"profileType": "public",
"dataShare": true,
"tems": true
},
"extras": {
"locationId": "xyz",
"contactId": "abc",
"workflowId": "def"
},
"meta": {
"key": "custom_action_key",
"version": "1.0"
}
}
Custom code
Custom Code allows users to create custom logic they want to achieve. This provides flexibility and
control beyond the pre-built APIs, enabling users to automate complex tasks and integrate with
various services not supported by API.
Code Editor
You can write the code in the Code Editor
You can input HTTP requests like Get, Put, Post, Delete etc via the button.
You can also use custom values using the picker.
Output should be a JavaScript Object or Array of Objects.
Testing the code is a mandatory step, if the test is not done then user will not be able to use the
output of the code in the subsequent steps.
To test the code click on the "Test Code" button.
Post clicking on Run test button, if there are no errors in the code them it will show "Test Result
Success" and if there is an error in code then the result will be "Test Result Failed" and you
would have to recheck the code to remove the error.
You can also format the code using "Format code" button.
Pause Execution
This toggle is used the contact will be held at this action unless resume webhook is requested.
If this toggle is true then provided extras object needs to be passed as body payload for resume
workflow endpoint.
Show API details button shows a sample response to be passed onto to the webhook for Success
Execution and Failed Execution.
Sync: When the pause execution is turned off along with branching support, the contact will be
moved to provided branch using branchId property from API response or from Custom Code
using return statement. The branchId here will be the branch through with the contact will
move forward.
Async: When the pause execution is turned off, the branch ID needs to be sent to the webhook
for resuming which is present in "show API details" button. More info present in Pause
functionality.
Response Data
Add sample response data to configure custom variables.
Enter a valid sample response JSON structure that will be sent as a response to the Send Data API
endpoint.
Arrays are supported in response data. This data can be utilized in custom variables based on
references and is available for use in Array Functions, Custom Code, and Custom Webhooks.
The action version will be in draft state by default. After updating the action information and
configuration the action version should be submitted for review.
Click on Submit for review and add required changelog information for the submitted version.
Once approved the version submitted for review will be published live to all Sub-accounts.
Delete Action
Once an Action is deleted, it will be deleted permanently and cannot be restored. The deleted action
will be removed from Marketplace App and Workflow Action list. If a deleted action is part of any
workflow the action execution will be skipped.
Enter action name to confirm delete
For more detailed information, refer to the official HighLevel guide on Marketplace Workflow
Actions.
Marketplace Modules Workflow Actions and Triggers Marketplace Workflow Triggers
Creating a Marketplace
Workflow Trigger
Marketplace Workflow Triggers are the customizable workflow triggers managed in Marketplace.
You will be able to create custom triggers to push data from your application/API to a workflow.
{
"options": [
{ "label": "Afghanistan", "value": "AF" },
{ "label": "Åland Islands", "value": "AX" },
{ "label": "Albania", "value": "AL" },
{ "label": "Algeria", "value": "DZ" },
{ "label": "American Samoa", "value": "AS" }
]
}
Type: Dynamic
Dynamic filters are used to build custom filters from an API call. The API call should return the below
response structure to construct the filters in the Workflow trigger configuration form UI. Only one
Dynamic type can be created per trigger.
URL (POST) Enter your API endpoint URL. When executed data is sent to this API endpoint via POST
method in the below mentioned payload format and a valid response is expected as per the sample
response structure shared below.
Sample Payload: The form data is sent as payload to the dynamic field API
{
"data": {
"name": "John Doe",
"age": "29",
"gender": "male",
"hobbies": ["sports", "music"],
"address": "My Address",
"country": "US",
"profileType": "public"
},
"extras": {
"locationId": "xyz",
"contactId": "abc",
"workflowId": "def"
},
"meta": {
"key": "custom_trigger_key",
"version": "1.0"
}
}
{
"filters": [
{ "field": "name", "title": "Name", "fieldType": "string", "required": true
},
{ "field": "gender", "title": "Gender", "fieldType": "select", "required":
true,
"options": [
{ "label": "Male", "value": "male" },
{ "label": "Female", "value": "female" }
]
}
]
}
String
Select
{
"field": "gender",
"title": "Gender",
"fieldType": "select",
"required": true,
"options": [
{ "label": "Male", "value": "male" },
{ "label": "Female", "value": "female" }
]
}
Multiple Select
{
"field": "hobbies",
"title": "Hobbies",
"fieldType": "multiselect",
"required": true,
"options": [
{ "label": "Sport", "value": "sport" },
{ "label": "Music", "value": "music" }
]
}
{
"triggerData": {
"id": "def",
"key": "trigger_a",
"filters": [],
"eventType": "CREATED",
"targetUrl": "[Link]
marketplace/triggers/execute/abc/def"
},
"meta": { "key": "trigger_a", "version": "2.4" },
"extras": { "locationId": "ghj", "workflowId": "qwe", "companyId": "asd" }
}
{
"triggerData": {
"id": "def",
"key": "trigger_a",
"filters": [
{
"field": "country",
"id": "country",
"operator": "==",
"title": "Country",
"type": "select",
"value": "USA"
}
],
"eventType": "UPDATED",
"targetUrl": "[Link]
marketplace/triggers/execute/abc/def"
},
"meta": { "key": "trigger_a", "version": "2.4" },
"extras": { "locationId": "ghj", "workflowId": "qwe", "companyId": "asd" }
}
{
"triggerData": {
"id": "def",
"key": "trigger_a",
"filters": [
{
"field": "country",
"id": "country",
"operator": "==",
"title": "Country",
"type": "select",
"value": "USA"
}
],
"eventType": "DELETED",
"targetUrl": "[Link]
marketplace/triggers/execute/abc/def"
},
"meta": { "key": "trigger_a", "version": "2.4" },
"extras": { "locationId": "ghj", "workflowId": "qwe", "companyId": "asd" }
}
Version Management
Create New Version: Click on "+ New Version" to create a new draft version of the trigger. This
version will prefill all previously published data.
Submit for Review: Each new version must be submitted for review and approved before it
becomes live.
Delete Trigger
To delete a trigger, enter the trigger name to confirm deletion.
Examples:
Send order data to trigger and add the order information to google sheet, use if/else to
categorize based on order value and send a slack notification.
Retrieve the contact with Contact ID using Find contact action
For more detailed information, refer to the official HighLevel guide on Marketplace Workflow
Triggers.
Search / Ask AI
Assistants Tools
Custom Tools
Learn how to create and configure Custom Tools for use by your Vapi assistants.
This guide shows you how to create custom tools for your Vapi assistants. We recommend using
the Vapi dashboard’s dedicated Tools section, which provides a visual interface for creating and
managing tools that can be reused across multiple assistants. For advanced users, API
configuration is also available.
2. Tool Name: Give your tool a descriptive name (e.g., “Weather Lookup”)
4. Tool Configuration:
Set up the messages your assistant will speak during tool execution. For example, if you want
custom messages you can add something like this:
Dashboard Configuration
1. Tool Name: “Weather Lookup”
4. Parameters:
This example uses OpenWeatherMap’s free API. You’ll need to sign up at [Link] to
get a free API key and add it as a query parameter: ?appid=YOUR_API_KEY&q={location}
Messages Configuration
⦁ Request Failed: “I’m having trouble accessing weather data right now.”
In the Dashboard
3. Click Add Tool and select your custom tool from the dropdown
In Workflows
Tools created in the Tools section are automatically available in the workflow builder:
Use the Vapi CLI to forward tool calls to your local server:
vapi listen is a local forwarder that requires a separate tunneling service. Configure your tool’s
server URL to use the tunnel’s public URL for testing. Learn more →
For advanced users who prefer programmatic control, you can also create and manage tools via
the Vapi API:
When your server receives a tool call request from Vapi, it will be in the following format:
1 {
2 "message": {
3 "timestamp": 1678901234567,
4 "type": "tool-calls",
5 "toolCallList": [
6 {
7 "id": "toolu_01DTPAzUm5Gk3zxrpJ969oMF",
8 "name": "get_weather",
9 "arguments": {
10 "location": "San Francisco"
11 }
12 }
13 ],
14 "toolWithToolCallList": [
15 {
16 "type": "function",
17 "name": "get_weather",
18 "parameters": {
19 "type": "object",
20 "properties": {
When your Vapi assistant calls a tool (via the server URL you configured), your server will receive
an HTTP request containing information about the tool call. Upon processing the request and
executing the desired function, your server needs to send back a response in the following JSON
format:
1 {
2 "results": [
3 {
4 "toolCallId": "X",
5 "result": "Y"
6 }
7 ]
8 }
⦁ toolCallId (X): This is a unique identifier included in the initial request from Vapi. It allows the
assistant to match the response with the corresponding tool call, ensuring accurate processing
and context preservation.
⦁ result (Y): This field holds the actual output or result of your tool’s execution. The format and
content of “result” will vary depending on the specific function of your tool. It could be a
string, a number, an object, an array, or any other data structure that is relevant to the tool’s
purpose.
Example:
Let’s revisit the weather tool example from before. If the tool successfully retrieves the weather for
a given location, the server response might look like this:
1 {
2 "results": [
3 {
4 "toolCallId": "call_VaJOd8ZeZgWCEHDYomyCPfwN",
5 "result": "San Francisco's weather today is 62°C, partly cloudy."
6 }
7 ]
8 }
⦁ Pay attention to the required parameters and response format of your functions.
⦁ Ensure your server is accessible and can handle the incoming requests from Vapi.
⦁ Make sure to add “Tools Calls” in both the Server and Client messages and remove the
function calling from it.
By following these guidelines and adapting the sample payload, you can easily configure a variety
of tools to expand your Vapi assistant’s capabilities and provide a richer, more interactive user
experience.
Video Tutorial:
Tools Tutorial - Step by Step - Vapi - Functions, DTMF, End Call, Transfers, API
Was this page helpful? Yes No Edit this page
Code Tool
Previous Next
Execute custom TypeScript code directly within your assistant without setti…
Built with
Search / Ask AI
Assistants Tools
Troubleshoot and fix common issues with custom tool integrations in your Vapi assistants.
Quick diagnosis
Use the exact tool name in your assistant instructions. If your tool is named get_weather , reference
get_weather in prompts, not weather_tool .
Tool schema
1 {
2 "name": "get_weather",
3 "parameters": {
4 "type": "object",
5 "properties": {
6 "city": {
7 "type": "string",
8 "description": "City name for weather lookup"
9 }
10 },
11 "required": ["city"] // Must be array of required parameter names
12 }
13 }
Tool configuration
1 {
2 "name": "get_weather",
3 "description": "Get current weather for a city",
4 "parameters": {
5 // ... your parameters
6 },
7 "strict": true,
8 "maxTokens": 500
9 }
Check your call logs for “Schema validation errors” to identify parameter issues.
1 {
2 "results": [
3 {
4 "toolCallId": "call_123",
5 "result": "Your response as single-line string"
6 }
7 ]
8 }
1 {
2 "results": [
3 {
4 "toolCallId": "call_123",
5 "result": "Temperature: 72°F\nCondition: Sunny\nHumidity: 45%"
6 }
7 ]
8 }
Ensure your webhook returns HTTP 200. Any other status code causes the response to be
ignored.
For multiple tools, return results in the same order as calls were triggered, with matching
toolCallId values.
Token truncation
The default token limit is only 100. Increase it for complex tools:
Tool configuration
1 {
2 "name": "complex_tool",
3 "description": "Tool that needs more tokens",
4 "parameters": {
5 // ... your parameters
6 },
7 "maxTokens": 500 // Increase from default 100
8 }
Look for “Token truncation warnings” in your call logs to identify when this occurs.
Return all results in the same order as the calls were triggered:
1 {
2 "results": [
3 {
4 "toolCallId": "call_1",
5 "result": "First tool success"
6 },
7 {
8 "toolCallId": "call_2",
9 "error": "Second tool failed"
10 },
11 {
12 "toolCallId": "call_3",
13 "result": "Third tool success"
14 }
15 ]
16 }
Use HTTP 200 for the entire response, even if some individual tools error. Handle errors within the
results array using the error field.
Behavior:
1 {
2 "name": "sync_tool",
3 "async": false, // or omit (default)
4 // ... other config
5 }
Most tools should use sync behavior unless you specifically need async processing for long-running
operations.
1 {
2 "results": [
3 {
4 "toolCallId": "call_123",
5 "result": "Single-line string response"
6 }
7 ]
8 }
1 {
2 "name": "tool_name",
3 "description": "Clear description of what the tool does",
4 "parameters": {
5 "type": "object",
6 "properties": {
7 "param1": {
8 "type": "string",
9 "description": "Parameter description"
10 }
11 },
12 "required": ["param1"]
13 },
14 "strict": true,
15 "maxTokens": 500,
16 "async": false
17 }
”ok, no result returned” Wrong response format Use correct JSON structure
”HTTP errors” Webhook not returning 200 Return HTTP 200 always
Built with
Search / Ask AI
Assistants Tools
Default Tools
Adding Transfer Call, End Call, Dial Keypad, and API Request capabilities to your assistants.
Vapi voice assistants are given additional functions: transferCall , endCall , sms , dtmf (to dial a
keypad with DTMF ), and apiRequest . These functions can be used to transfer calls, hang up
calls, send SMS messages, enter digits on the keypad, and integrate business logic with your
existing APIs.
To add Default Tools to your agent, you need to add them in the tools array of your assistant. You
can do this in your api request, or by creating a new tool in the dashboard tools page, and assigning
it to your assistant.
Transfer Call
This function is provided when transferCall is included in the assistant’s list of available tools
(see configuration options here). This function can be used to transfer the call to any of the
destinations defined in the tool configuration (see details on destination options here).
1 {
2 "model": {
3 "provider": "openai",
4 "model": "gpt-4o",
5 "messages": [
6 {
7 "role": "system",
8 "content": "You are an assistant at a law firm. When the user asks to be tran
9 }
10 ],
11 "tools": [
12 {
13 "type": "transferCall",
14 "destinations" : {
15 {
16 "type": "number",
17 "number": "+16054440129"
18 }
19 }
20 }
2 ]
End Call
This function is provided when endCall is included in the assistant’s list of available tools (see
configuration options here). The assistant can use this function to end the call.
1 {
2 "model": {
3 "provider": "openai",
4 "model": "gpt-4o",
5 "messages": [
6 {
7 "role": "system",
8 "content": "You are an assistant at a law firm. If the user is being mean, us
9 }
10 ],
11 "tools": [
12 {
13 "type": "endCall"
14 }
15 ]
16 }
17 }
Send Text
This function is provided when sms is included in the assistant’s list of available tool (see
configuration options here). The assistant can use this function to send SMS messages using a
configured Twilio account.
1 {
2 "model": {
3 "provider": "openai",
4 "model": "gpt-4o",
5 "messages": [
6 {
7 "role": "system",
8 "content": "You are an assistant. When the user asks you to send a text messa
9 }
10 ],
11 "tools": [
12 {
13 "type": "sms",
14 "metadata": {
15 "from": "+15551234567"
16 }
17 }
18 ]
19 }
20 }
This function is provided when dtmf is included in the assistant’s list of available tools (see
configuration options here). The assistant will be able to enter digits on the keypad. Useful for IVR
navigation or data entry.
1 {
2 "model": {
3 "provider": "openai",
4 "model": "gpt-4o",
5 "messages": [
6 {
7 "role": "system",
8 "content": "You are an assistant at a law firm. When you hit a menu, use the
9 }
10 ],
11 "tools": [
12 {
13 "type": "dtmf"
14 }
15 ]
16 }
17 }
1. In-band: tones are transmitted as part of the regular audio stream. This is the simplest
method, but it can suffer from quality issues if the audio stream is compressed or degraded.
2. Out-of-band via RFC 2833: tones are transmitted separately from the audio stream, within
RTP (Real-Time Protocol) packets. It’s typically more reliable than in-band DTMF, particularly
for VoIP applications where the audio stream might be compressed. RFC 2833 is the standard
that initially defined this method. It is now replaced by RFC 4733 but this method is still
referred by RFC 2833.
3. Out-of-band via SIP INFO messages: tones are sent as separate SIP INFO messages. While
this can be more reliable than in-band DTMF, it’s not as widely supported as the RFC 2833
method.
Vapi’s DTMF tool integrates with telephony provider APIs to send DTMF tones using the out-of-band
RFC 2833 method. This approach is widely supported and more reliable for transmitting the signals,
especially in VoIP environments. Note, the tool’s effectiveness depends on the IVR system’s
configuration and their capturing method. See our IVR navigation guide for best practices.
API Request
This tool allows your assistant to make HTTP requests to any external API endpoint during
conversations. This tool fills the gap between Vapi and your existing business logic, bringing your
own endpoints into the conversation flow. See configuration options here.
Use LiquidJS syntax to reference conversation variables and user data in your URLs, headers, and
request bodies. This allows your API requests to adapt dynamically based on the conversation
context.
Basic Examples
1 {
2 "model": {
3 "provider": "openai",
4 "model": "gpt-4o",
5 "messages": [
6 {
7 "role": "system",
8 "content": "You help users check their order status. When they provide an ord
9 }
10 ],
11 "tools": [
12 {
13 "type": "apiRequest",
14 "function": {
15 "name": "api_request_tool"
16 },
17 "name": "checkOrderStatus",
18 "url": "[Link]
19 "method": "GET",
20 "body": {
1 {
2 "model": {
3 "provider": "openai",
4 "model": "gpt-4o",
5 "messages": [
6 {
7 "role": "system",
8 "content": "You help users book appointments. When they want to schedule, use
9 }
10 ],
11 "tools": [
12 {
13 "type": "apiRequest",
14 "function": {
15 "name": "api_request_tool"
16 },
17 "name": "bookAppointment",
18 "url": "[Link]
19 "method": "POST",
20 "headers": {
21 "type": "object"
Advanced Configuration
1 {
2 "type": "apiRequest",
3 "function": {
4 "name": "api_request_tool"
5 },
6 "name": "checkOrderStatus",
7 "url": "[Link]
8 "method": "GET",
9 "body": {
10 "type": "object",
11 "properties": {
12 "orderNumber": {
13 "description": "The user's order number",
14 "type": "string"
15 }
16 },
17 "required": [
18 "orderNumber"
19 ]
20 },
Voicemail Tool
Previous Next
Learn how to use the assistant-controlled voicemail tool for flexible voice…
Built with
OAuth 2.0 OAuth 2.0 Get Access Token
Request
APPLICATION/X-WWW-FORM-URLENCODED
BODY REQUIRED
code string
refresh_token string
user_type string
The type of token to be requested
Possible values: [ Company , Location ]
Example: Location
redirect_uri string
The redirect URI for your application
Example: [Link]
APPLICATION/JSON
SCHEMA
access_token string
Example: ab12dc0ae1234a7898f9ff06d4f69gh
token_type string
Example: Bearer
expires_in number
Example: 86399
refresh_token string
Example: xy34dc0ae1234a4858f9ff06d4f66ba
scope string
Example: conversations/[Link] conversations/[Link]
userType string
Example: Location
locationId string
Location ID - Present only for Sub-Account Access Token
Example: l1C08ntBrFjLS0elLIYU
companyId string
Company ID
Example: l1C08ntBrFjLS0elLIYU
approvedLocations string[]
Approved locations to generate location access token
Example: ["l1C08ntBrFjLS0elLIYU"]
isBulkInstallation boolean
Example: Bearer
★★★★★
CURL
Base URL
[Link]
Body REQUIRED
client_id REQUIRED
client_secret REQUIRED
client_secret
grant_type REQUIRED
---
code
code
refresh_token
refresh_token
user_type
---
redirect_uri
RESPONSE CLEAR
Click the Send API Request button above and see the response here!
OAuth 2.0 OAuth 2.0 Get Location Access Token from Agency Token
Requirements
Scope(s)
[Link]
Auth Method(s)
Token Type(s)
Agency Token
Request
HEADER PARAMETERS
APPLICATION/X-WWW-FORM-URLENCODED
BODY REQUIRED
Successful response
APPLICATION/JSON
SCHEMA
access_token string
Location access token which can be used to authenticate & authorize API under following scope
Example: ab12dc0ae1234a7898f9ff06d4f69gh
token_type string
Example: Bearer
expires_in number
Time in seconds remaining for token to expire
Example: 86399
scope string
Scopes the following accessToken have access to
Example: conversations/[Link] conversations/[Link]
locationId string
Location ID - Present only for Sub-Account Access Token
Example: l1C08ntBrFjLS0elLIYU
planId string
Plan Id of the subscribed plan in paid apps.
Example: l1C08ntBrFjLS0elLIYU
AUTHORIZATION: AUTHORIZATION
CURL
Base URL
[Link]
Auth
Bearer Token
Bearer Token
Parameters
---
Body REQUIRED
companyId REQUIRED
locationId REQUIRED
The location ID for which you want to obtain accessToken
RESPONSE CLEAR
Click the Send API Request button above and see the response here!
OAuth 2.0 OAuth 2.0 Get Location where app is installed
This API allows you fetch location where app is installed upon
Requirements
Scope(s)
[Link]
Auth Method(s)
Token Type(s)
Agency Token
Request
HEADER PARAMETERS
QUERY PARAMETERS
skip string
Parameter to skip the number installed locations
Default value: 0
Example: 1
limit string
Parameter to limit the number installed locations
Default value: 20
Example: 10
query string
Parameter to search for the installed location by name
Example: location name
isInstalled boolean
Filters out location which are installed for specified app under the specified company
Example:
versionId string
VersionId of the app
Example: tDtDnQdgm2LXpyiqYvZ6
onTrial boolean
Filters out locations which are installed for specified app in trial mode
Example:
planId string
Filters out location which are installed for specified app under the specified planId
Example:
Successful response
APPLICATION/JSON
SCHEMA
locations object[]
count number
Total location count under the company
Example: 1231
installToFutureLocations boolean
Boolean to control if user wants app to be automatically installed to future locations
Example: true
★★★★★
AUTHORIZATION: AUTHORIZATION
CURL
1 curl -L '[Link] \
2 -H 'Accept: application/json' \
3 -H 'Authorization: Bearer <TOKEN>'
Base URL
[Link]
Auth
Bearer Token
Bearer Token
Parameters
---
RESPONSE CLEAR
Click the Send API Request button above and see the response here!
Search / Ask AI
Get started
Guides
Explore real-world, cloneable examples to build voice agents with Assistants and Squads
Create an outbound sales agent that can Build a structured multilingual support
schedule appointments automatically workflow with language selection and
dedicated conversation paths
Build a docs agent that can answer Build a technical support assistant that
questions about your documentation remembers where you left off between
calls
Easily integrate the Vapi Voice Widget Build voice AI agents faster with the Vapi
into your website for enhanced user CLI - project integration, local testing,
interaction and IDE enhancement
Was this page helpful? Yes No Edit this page
Built with
Authorization OAuth 2.0 Access Token Generation: Agency vs. Sub-Account Scenarios
Overview
For apps whose Target User is set as Agency, the app will only be visible to the Agency
Admin/Owner, and only they can install it.
Installation Flow
1. Install the app on your Agency account.
2. After installation, the redirect URL will be triggered from our end, and the authorization code
will be shared.
3. Use this authorization code to exchange for an Access Token using the Get Access Token API
endpoint.
Note: The Access Token generated will be of user type company(Agency Level Token).
Sample Request
Sample Response
{
"access_token":
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdXRoQ2xhc3MiOiJDb21wYW55IiwiYXV0aENsYQ",
"token_type": "Bearer",
"expires_in": 86399,
"refresh_token":
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdXRoQ2xhc3MiOiJDb21wYW55IiwiYXV0aEN",
"scope": "[Link]",
"refreshTokenId": "68a2feef89153fe9b8d196bc",
"userType": "Company",
"companyId": "GNb7aIv4rQFVb9iwNl5K",
"isBulkInstallation": false,
"userId": "Rg6BRRiHh7dS9gJy3W8a"
}
Authorization OAuth 2.0 Access Token Generation: Agency vs. Sub-Account Scenarios
Installation Options
When you set the target user to Sub-Account during app creation, you can configure who can install
the app. The type of token generated depends on the option chosen and who installs the app.
Installation Flow
⚠️ Note: The Access Token generated here will be of type Company (Agency-level).
Sample Request
curl --request POST
--url [Link]
--header 'Accept: application/json'
--header 'Content-Type: application/x-www-form-urlencoded'
--data-urlencode client_id=68a32958b5154ca8bbdc4d40-meh5chaj
--data-urlencode client_secret=a5949eb7-4d46-4bfd-95c1-e338d4952e6b
--data-urlencode grant_type=authorization_code
--data-urlencode code=059ff0439402599b0ecb45388a9d4b9fc2d17123
--data-urlencode user_type=Company
Sample Response
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 86399,
"refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"scope": "[Link]",
"refreshTokenId": "68a32a7fb5154c26d5dd218c",
"userType": "Company",
"companyId": "GNb7aIv4rQFVb9iwNl5K",
"isBulkInstallation": true,
"userId": "Rg6BRRiHh7dS9gJy3W8a"
}
4. To access Sub-Account–specific API endpoints, the Agency-level Access Token must first be
exchanged for a Sub-Account (Location-level) Access Token. This exchange can be performed
using the Get Location Access Token from Agency Token API.
Note: You can configure a webhook URL for your app, and the App Install event will
automatically be subscribed by default.
When the APP is installed this event will be triggered, this webhook provides details such as the
locationId where the app has been installed. You can use the locationId along with your
Agency-level Access Token to exchange it for a Sub-Account (Location-level) Access Token.
Sample Request for Get Location Access Token from Agency Token
curl -L '[Link]
-H 'Content-Type: application/x-www-form-urlencoded'
-H 'Accept: application/json'
-H 'Version: 2021-07-28'
-H 'Authorization: Bearer {AGENCY_ACCESS_TOKEN}'
-d 'companyId=GNb7aIv4rQFVb9iwNl5K'
-d 'locationId=HjiMUOsCCHCjtxzEf8PR'
Sample Response
{
"access_token":
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI2OGEzMmRhNjlkN2EzY2E5NT",
"token_type": "Bearer",
"expires_in": 86400,
"refresh_token":
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdXRoQ2xhc3MiOiJMb2NhdGlvbiIsImF",
"scope": "[Link] [Link] [Link]",
"userType": "Location",
"companyId": "GNb7aIv4rQFVb9iwNl5K",
"locationId": "HjiMUOsCCHCjtxzEf8PR",
"userId": "Rg6BRRiHh7dS9gJy3W8a",
"traceId": "8cf33664-9f4f-4392-adf6-71b8bed2592a"
}
Installation Flow
⚠️ Note: The Access Token generated here will be of type Company (Agency-level).
Sample Request
Sample Response
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 86399,
"refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"scope": "[Link]",
"refreshTokenId": "68a32a7fb5154c26d5dd218c",
"userType": "Company",
"companyId": "GNb7aIv4rQFVb9iwNl5K",
"isBulkInstallation": true,
"userId": "Rg6BRRiHh7dS9gJy3W8a"
}
4. To access Sub-Account–specific API endpoints, the Agency-level Access Token must first be
exchanged for a Sub-Account (Location-level) Access Token. This exchange can be performed
using the Get Location Access Token from Agency Token API.
Note: You can configure a webhook URL for your app, and the App Install event will
automatically be subscribed by default.
When the APP is installed this event will be triggered, this webhook provides details such as the
locationId where the app has been installed. You can use the locationId along with your
Agency-level Access Token to exchange it for a Sub-Account (Location-level) Access Token.
{
"type": "INSTALL",
"appId": "665c6bb13d4e5364bdec0e2f",
"versionId": "665c6bb13d4e5364bdec0e2f",
"installType": "Location",
"locationId": "HjiMUOsCCHCjtxzEf8PR",
"companyId": "GNb7aIv4rQFVb9iwNl5K",
"userId": "Rg6BRRiHh7dS9gJy3W8a",
"companyName": "Marketplace and Integrations Prod Agency",
"isWhitelabelCompany": true,
"whitelabelDetails": {
"logoUrl": "[Link]
"domain": "[Link]"
},
"timestamp": "2025-06-25T06:57:06.225Z",
"webhookId": "1a533f85-1f1e-4886-891e-ee0cf4666e90"
}
Sample Request for Get Location Access Token from Agency Token
curl -L '[Link]
-H 'Content-Type: application/x-www-form-urlencoded'
-H 'Accept: application/json'
-H 'Version: 2021-07-28'
-H 'Authorization: Bearer {AGENCY_ACCESS_TOKEN}'
-d 'companyId=GNb7aIv4rQFVb9iwNl5K'
-d 'locationId=HjiMUOsCCHCjtxzEf8PR'
Sample Response
{
"access_token":
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI2OGEzMmRhNjlkN2EzY2E5NT",
"token_type": "Bearer",
"expires_in": 86400,
"refresh_token":
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdXRoQ2xhc3MiOiJMb2NhdGlvbiIsImF",
"scope": "[Link] [Link] [Link]",
"userType": "Location",
"companyId": "GNb7aIv4rQFVb9iwNl5K",
"locationId": "HjiMUOsCCHCjtxzEf8PR",
"userId": "Rg6BRRiHh7dS9gJy3W8a",
"traceId": "8cf33664-9f4f-4392-adf6-71b8bed2592a"
}
Installation Flow
{
"access_token":
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdXRoQ2xhc3MiOiJMb2NhdGlvbiIsImF1dGhDbGFzc
"token_type": "Bearer",
"expires_in": 86399,
"refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdXRoQ2xhc3MiOiJMb2N",
"scope": "[Link]",
"refreshTokenId": "68a4332c2a64bbc7a1888971",
"userType": "Location",
"companyId": "GNb7aIv4rQFVb9iwNl5K",
"locationId": "HjiMUOsCCHCjtxzEf8PR",
"isBulkInstallation": false,
"userId": "57n5nmVqHA1ghBM8UKhU"
}
Summary
Agency-only installation: If “Who can install the app” is set to Agency only, the generated
token will be of type Company (Agency-level). To run APIs and perform actions at the Sub-
Account level, this token must be exchanged for a Location-level token.
Everyone installation: If “Who can install the app” is set to Everyone, there are two possible
scenarios:
Agency User Installs the APP → The generated token will be of type Company (Agency-
level). To run APIs and perform actions at the Sub-Account level, this token must be
exchanged for a Location-level token.
Sub-Account User Installs the APP → The generated token will be of type Location . This
token can be used directly to call APIs and perform tasks without further exchange.
Search / Ask AI
Get started
Introduction
Build voice AI agents that can make and receive phone calls
What is Vapi?
Vapi is the developer platform for building voice AI agents. We handle the complex infrastructure
so you can focus on creating great voice experiences.
⦁ Handle complex workflows like appointment scheduling, customer support, and more
You have full control over each component, with dozens of providers and models to choose from;
OpenAI, Anthropic, Google, Gladia, Deepgram, ElevenLabs, and many, many more.
Vapi offers two main primitives, designed for different use cases:
Assistants Squads
Best for: Most use cases and fast Best for: Multi-assistant setups with
iteration specialization
Key capabilities
Build your first voice agent in 5 minutes Embed live voice conversations directly in
using our dashboard. your app.
Developer tools
Vapi CLI
The Vapi CLI brings the full power of the platform to your terminal:
CLI Overview
Install in seconds with:
Automate inbound support calls with Make outbound sales calls, qualify leads,
agents that can access your knowledge and schedule appointments with
base and escalate to humans when sophisticated branching logic.
needed.
support workflows.
Phone calls
Next
Learn to make your first phone call with a voice agent
Built with
Search / Ask AI
Get started
Phone calls
Learn to make your first phone call with a voice agent
Overview
Vapi makes it easy to build voice agents that can make and receive phone calls. In under 5
minutes, you’ll create a voice assistant and start talking to it over the phone.
Prerequisites
⦁ A Vapi account
Using the Vapi CLI? You can create assistants, manage phone numbers, and make calls directly from
your terminal:
In the dashboard, create a new assistant using the customer support specialist template.
Set the first message and system prompt for your assistant:
First message:
Hi there, this is Alex from TechSolutions customer support. How can I help you toda
System prompt:
You are Alex, a customer service voice assistant for TechSolutions. Your primary pu
- Sound friendly, patient, and knowledgeable without being condescending
- Use a conversational tone with natural speech patterns
- Speak with confidence but remain humble when you don't know something
- Demonstrate genuine concern for customer issues
In the Phone Numbers tab, create a free US phone number or import an existing number
from another provider.
Select your assistant in the inbound settings for your phone number. When this number is
called, your assistant will automatically answer.
Call the phone number you just created. Your assistant will pick up and start the
conversation with your configured first message.
You can also test your assistant directly in the dashboard by clicking the call button—no
phone number required.
Next steps
⦁ Customize the conversation: Update the system prompt to match your use case
⦁ Configure models: Try different speech and language models for better performance
⦁ Scale with APIs: Use Vapi’s REST API to create assistants programmatically
Ready to integrate voice into your application? Check out the Web integration guide to embed voice
calls directly in your app.
Web calls
Previous Next
Build voice interfaces and backend integrations using Vapi's Web and Serv…
Built with
Authorization Private Integrations Token
Private Integrations
Private Integrations allow you to build powerful custom integrations between your HighLevel
account and any other third-party app.
If you are looking to integrate your HighLevel account with a third-party app, you have two options:
1. Find and install the relevant app from the App Marketplace
2. Build your own private integration by yourself or with the help of a developer using APIs.
Video Walkthrough
More Features: API v2.0 has more powerful APIs Less Features: API v1.0 has limited APIs
Example:
For a full list of available endpoints and testing capabilities, visit our official developer
documentation.
Navigate to:
Settings > Team > Edit the specific agency admin > Roles & Permissions, and enable/disable
Private Integrations for the agency admin.
Allow the agency admin to view and manage the agency's private integrations
Allow the agency admin to view and manage the sub-accounts' private integrations
Note: Please ensure that you are sharing the token with trusted parties only. Do not share it
publicly.
Don't forget to copy the token generated as you won't be able to do it again later.
You will have a 7-day window where both the old and the new tokens will continue to work. After 7
days, the old token will expire.
Note: Don't forget to copy the token generated as you won't be able to do it again later.
How:
1. Navigate to Private Integrations under settings, and select "Edit" from the three-dot menu.
2. Update the Private Integration name and description if required. Click on "Next".
3. If required, update the scopes/permissions that you want the private integration to have access
to on your account. Ensure that you are selecting only the required scopes for better data
security. Click on "Update" to save the updates made.
Note: Updating the Private Integration details does not generate a new token. The existing
token will continue to work.
To do so, navigate to Private Integrations under settings, and select "Delete" from the three-dot
menu.
★★★★★
Search / Ask AI
Get started
Vapi CLI
Overview
The Vapi CLI is the official command-line interface that brings world-class developer experience to
your terminal and IDE. Build, test, and deploy voice AI applications without leaving your
development environment.
Installation
Quick start
1 Authenticate
$ vapi login
$ vapi init
The CLI auto-detects your tech stack and sets up everything you need.
Key features
🚀 Project integration
Drop Vapi into any existing codebase with intelligent auto-detection:
$ vapi init
$ # Detected: [Link] application
$ # ✓ Installed @vapi-ai/web SDK
$ # ✓ Generated components/[Link]
$ # ✓ Created pages/api/vapi/[Link]
$ # ✓ Added environment template
Supports React, Vue, [Link], Python, Go, Flutter, React Native, and dozens more frameworks.
🤖 MCP integration
Turn your IDE into a Vapi expert with Model Context Protocol:
Your IDE’s AI assistant (Cursor, Windsurf, VSCode) gains complete, accurate knowledge of Vapi’s
APIs and best practices. No more hallucinated code or outdated examples.
Important: vapi listen is a local forwarder only - it does NOT provide a public URL. You need a
separate tunneling service (like ngrok) to expose the CLI’s port to the internet. Update your webhook
URLs in Vapi to use the tunnel’s public URL.
🔐 Multi-account management
Switch between organizations and environments seamlessly:
Common commands
Assistant management
Call operations
Configuration
The CLI stores configuration in ~/.[Link] . You can also use environment variables:
Auto-updates
The CLI automatically checks for updates and notifies you when new versions are available:
Next steps
Resources:
⦁ GitHub Repository
⦁ Report Issues
⦁ Discord Community
Was this page helpful? Yes No Edit this page
Assistants quickstart
Previous Next
Build your first assistant and make a phone call in minutes
Built with
Search / Ask AI
Assistants Tools
Voicemail Tool
Learn how to use the assistant-controlled voicemail tool for flexible voicemail handling
Overview
The voicemail tool gives your assistant direct control over when and how to leave voicemail
messages. Unlike automatic voicemail detection, which operates independently of your assistant,
this tool allows your assistant to decide when it’s reached a voicemail system and leave a
configured message.
Key benefits:
How it works
1. Your assistant listens for voicemail indicators (greetings mentioning “unavailable”, “leave a
message”, etc.)
Configuration
1 {
2 "model": {
3 "provider": "openai",
4 "model": "gpt-4o",
5 "messages": [
6 {
7 "type": "system",
8 "content": "You are a sales representative for Acme Corp. If at any point you
9 }
10 ],
11 "tools": [
12 {
13 "type": "voicemail",
14 "function": {
15 "name": "leave_voicemail",
16 "description": "Leave a voicemail message when you detect you've reached a
17 },
18 "messages": [
19 {
20 "type": "request-start",
21 "content": "Hi this is {{company}} {{message}} Please call us back at
Message Configuration
Text-to-Speech Messages
1 {
2 "messages": [
3 {
4 "type": "request-start",
5 "content": "Hi, this is {{company}}. {{message}}. Please call us back at {{phone
6 }
7 ]
8 }
Use template variables like {{ company }} , {{ message }} , and {{ phone }} to make your
voicemail messages dynamic while keeping them consistent.
For consistent quality and pronunciation, use pre-recorded audio files by providing the URL in the
content field:
1 {
2 "messages": [
3 {
4 "type": "request-start",
5 "content": "[Link]
6 }
7 ]
8 }
Pre-recorded audio messages are ideal for brand-specific messaging or when you need precise
pronunciation of phone numbers, website URLs, or company names.
Advanced Examples
1 {
2 "model": {
3 "provider": "openai",
4 "model": "gpt-4o",
5 "messages": [
6 {
7 "type": "system",
8 "content": "You are a sales representative calling prospects. If you reach vo
9 }
10 ],
11 "tools": [
12 {
13 "type": "voicemail",
14 "function": {
15 "name": "leave_voicemail",
16 "description": "Leave a professional pre-recorded voicemail message"
17 },
18 "messages": [
19 {
20 "type": "request-start",
21 "content": "[Link] com/professional sales voicemail mp3"
1 {
2 "model": {
3 "provider": "openai",
4 "model": "gpt-4o",
5 "messages": [
6 {
7 "type": "system",
8 "content": "You are calling leads about their recent inquiry. If you reach vo
9 }
10 ],
11 "tools": [
12 {
13 "type": "voicemail",
14 "function": {
15 "name": "leave_voicemail",
16 "description": "Leave a personalized voicemail message"
17 },
18 "messages": [
19 {
20 "type": "request-start",
21 "content": "Hi {{customer name}} this is {{agent name}} from {{company}}
Best Practices
Detection prompting
⦁ “unavailable”
⦁ “leave a message”
⦁ “voicemail”
⦁ “beep”
Message structure
Error handling
Avoid combining the voicemail tool with automatic detection, as this could result in false positives
and other complications.
Choose the voicemail tool when you need maximum flexibility and cost efficiency. Choose automatic
detection when you need guaranteed system-level detection without relying on assistant prompting.
Next steps
Custom Tools
Previous Next
Learn how to create and configure Custom Tools for use by your Vapi assis…
Built with
Search / Ask AI
Get started
Web calls
Build voice interfaces and backend integrations using Vapi's Web and Server SDKs
Overview
Build powerful voice applications that work across web browsers, mobile apps, and backend
systems. This guide covers both client-side voice interfaces and server-side call management
using Vapi’s comprehensive SDK ecosystem.
Developing locally? The Vapi CLI makes it easy to initialize projects and test webhooks:
Build browser-based voice assistants and widgets for real-time user interaction.
The fastest way to get started. Copy this snippet into your website:
1 <script>
2 var vapiInstance = null;
3 const assistant = "assistant_id"; // Substitute with your assistant ID
4 const apiKey = "your_public_api_key"; // Substitute with your Public key from Vapi
5 const buttonConfig = {}; // Modify this as required
6
7 (function (d, t) {
8 var g = [Link](t),
9 s = [Link](t)[0];
10 [Link] =
11 "[Link]
12 [Link] = true;
13 [Link] = true;
14 [Link](g, s);
15
16 [Link] = function () {
17 vapiInstance = [Link]({
18 apiKey: apiKey, // mandatory
19 assistant: assistant, // mandatory
20 config: buttonConfig, // optional
21 });
Automate outbound calls and handle inbound call processing with server-side SDKs.
Creating assistants
TypeScript Python Java Ruby C# Go
Bulk operations
Webhook integration
Next steps
Now that you understand both client and server SDK capabilities:
⦁ Explore use cases: Check out our examples section for complete implementations
⦁ Add tools: Connect your voice agents to external APIs and databases with custom tools
⦁ Configure models: Try different speech and language models for better performance
⦁ Scale with squads: Use Squads for multi-assistant setups and complex processes
Resources
Client SDKs:
⦁ C# SDK GitHub
⦁ Go SDK GitHub
Documentation:
⦁ API Reference
⦁ Discord Community
Guides
Previous Next
Explore real-world, cloneable examples to build voice agents with Assistan…
Built with
Marketplace Modules Web Widgets
Web Widgets
This guide aims to help developers create custom widgets for use in funnel builder and integrate
them seamlessly. We will cover how to create, set up, and render custom widgets using HTML, CSS,
and JavaScript or any JS frameworks like Angular, React, Vue along with communication between
your custom widget application and the funnel builder.
Prerequisites #
Basic knowledge of HTML, CSS, JavaScript or Experience with JS frontend frameworks (Angular,
React, Vue or similar)
Familiarity with iFrames.
Understanding of event-driven programming.
Overview
Custom widgets allow you to extend functionalities of a funnel builder by embedding custom
elements like price banners or other interactive components.
Step-by-Step Guide
Step 1: Register yourself as a developer on the App Marketplace
Develop an independent web application which allows users to interact with UI elements and
generate HTML, CSS and JS (if required) which will render the custom widget element based on the
settings that they choose.
The application should have the following functions which emits HTML, CSS and JS
createHtml() => Returns the HTML code for the widget
createJS() => Returns the JS code required for the widget to run in the website (optional)
createCss() => Returns the css code required for the widget styles.
The application should use postmate for iFrame communication between the funnel builder. The
widget code can be emitted to the funnel builder via an event emit.
Example:
parent?.emit('code', {
js: js as string,
})
Copy
Parameters:
html : HTML content required for widget to render along with styles
Example:
Note Please make sure you don't wrap your js code inside <script /> tag .
If its a JS based application then all the code required for interacting with the funnel/website
popup, or other JS events specified in the upcoming sections should be included in the JS
emitted to the parent
elementStore: All the variables that represents the settings of the widget (variable names can be
anything of your preference)
Example:
settings: {
widgetHeight: number
widgetWidth: number
image: string
}
Copy
On application initialization or the initial handshake, expect for the following payload
parent?.emit('code', {
html: html as string,
js: js as string,
elementStore: elementSettings as Object
})
Note: ensure that you emit the initial state Make sure that the data received is filled to all the
respective settings of your widgets so that we can show the previously saved values on revisits
1. Upload to Marketplace Build the project and upload the HTML, CSS & JS file or dist folder as a
zip to the marketplace app Ensure it adheres to the platform's guidelines and submission
requirements.
⚠️ Avoid using absolute path while building ensure you use relative paths in your project.
apps/
├── app1/
│ ├──[Link]
│ ├──css/
│ │ └── [Link]
│ └──js/
│ └── [Link]
└── app2/
├──[Link]
├──css/
│ └── [Link]
└──js/
└── [Link]
[Link]
Once approved and available in the marketplace, the funnel builder will list your widget under a
“Custom Widgets” or similar section.
Users can install the custom widget from the marketplace.
Drag and Drop Widget to Funnel Builder
Configure limited settings (like margin, padding, visibility, and custom classes) to be editable
directly from the funnel builder’s settings area.
Main widget settings should be configured through an external pop-up handled by your
application.
Ensure the funnel builder can render the widget by interpreting the generated HTML, CSS, and
JavaScript.
Using iFrames: Host(will take care of hosting) your settings application inside an iframe within the
funnel builder. Make sure it generates and communicates HTML, CSS, and JS code as settings are
adjusted.
Events and JS Integration: Custom widget events allow your custom widget to communicate with
the funnel preview environment. This communication is for creating interactive web applications
where actions in the widget can trigger responses in the funnel preview, resulting in a smoother and
more integrated user experience.
Key Concepts:
Event Emission: Your custom widget can send out signals (events) when users interact with it,
like clicking a button or changing a setting.
Event Handling: The funnel preview listens for these signals and performs certain actions in
response, like opening a popup or moving to the next step in a funnel.
Events:
1. customWidgetOpenPopup: This event triggers an action to open a popup on the preview side.
Example:
2. customWidgetGoToNextStep: This event triggers an action to move to the next step/page in the
funnel/website.
Example:
Note: If you're using any framework router, make sure you use it in createMemoryHistory. For
reference, see the Vue Router Memory Mode.
CSS Note: Ensure that if you are utilizing media query for mobile devices, you also take into
account the compatibility with the funnel builder mobile mode by targeting the class with a .--
mobile prefix.
Checklist
When developing and integrating custom widgets into a funnel builder, it's crucial to ensure they
function effectively without causing any disruptions or conflicts. Please test your app to ensure it
meets the criteria mentioned in this checklist before submitting the app for review.
Ensure it does not disrupt builder functionality: Verify that the widget integrates smoothly
and does not interfere with the core functionalities of the funnel builder.
Confirm it does not conflict with other elements: Ensure that your widget does not overlap
or interfere with other elements already present in the builder, which could lead to visual or
functional issues.
Check for any external scripts: Be vigilant about any unintended external scripts being
included with your widget, especially if it's not meant to have such inclusions. These could
introduce security risks or functionality conflicts.
Verify that it does not disrupt the white labeling process: If the application supports white
labeling, ensure that the widget preserves this capability and does not inadvertently expose
brand-specific details.
Ensure app state remains consistent and persistent: Confirm that the widget maintains its
state across various interactions and revisits, ensuring a consistent user experience.
Check that the initial state is correctly displayed: On loading, the widget should accurately
reflect the initial state as intended, displaying all predefined settings and configurations.
Test all settings to ensure they function properly: Go through each configurable setting
within the widget to verify they perform as expected, without bugs or unexpected behavior.
By carefully reviewing each of these points, you can assure the quality and reliability of your custom
widgets in the funnel builder environment. This checklist serves as a quality assurance tool to catch
potential issues before deployment.
Best Practice:
Developer Resources
For step-by-step technical instructions and best practices, please refer to the following resources:
★★★★★