openapi: 3.0.0
info:
title: Vapi Analytics Campaigns API
description: Vapi API — Analytics resource. Voice AI for developers.
version: '1.0'
contact:
name: Vapi
url: https://vapi.ai
servers:
- url: https://api.vapi.ai
security:
- bearer: []
tags:
- name: Campaigns
description: Campaigns endpoints.
paths:
/campaign:
post:
operationId: CampaignController_create
summary: Create Campaign
parameters: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateCampaignDTO'
responses:
'201':
description: ''
content:
application/json:
schema:
$ref: '#/components/schemas/Campaign'
tags:
- Campaigns
security:
- bearer: []
get:
operationId: CampaignController_findAll
summary: List Campaigns
parameters:
- name: id
required: false
in: query
schema:
type: string
- name: status
required: false
in: query
schema:
enum:
- scheduled
- in-progress
- ended
type: string
- name: page
required: false
in: query
description: This is the page number to return. Defaults to 1.
schema:
minimum: 1
type: number
- name: sortOrder
required: false
in: query
description: This is the sort order for pagination. Defaults to 'DESC'.
schema:
enum:
- ASC
- DESC
type: string
- name: sortBy
required: false
in: query
description: This is the column to sort by. Defaults to 'createdAt'.
schema:
enum:
- createdAt
- duration
- cost
type: string
- name: limit
required: false
in: query
description: This is the maximum number of items to return. Defaults to 100.
schema:
minimum: 0
maximum: 1000
type: number
- name: createdAtGt
required: false
in: query
description: This will return items where the createdAt is greater than the specified value.
schema:
format: date-time
type: string
- name: createdAtLt
required: false
in: query
description: This will return items where the createdAt is less than the specified value.
schema:
format: date-time
type: string
- name: createdAtGe
required: false
in: query
description: This will return items where the createdAt is greater than or equal to the specified value.
schema:
format: date-time
type: string
- name: createdAtLe
required: false
in: query
description: This will return items where the createdAt is less than or equal to the specified value.
schema:
format: date-time
type: string
- name: updatedAtGt
required: false
in: query
description: This will return items where the updatedAt is greater than the specified value.
schema:
format: date-time
type: string
- name: updatedAtLt
required: false
in: query
description: This will return items where the updatedAt is less than the specified value.
schema:
format: date-time
type: string
- name: updatedAtGe
required: false
in: query
description: This will return items where the updatedAt is greater than or equal to the specified value.
schema:
format: date-time
type: string
- name: updatedAtLe
required: false
in: query
description: This will return items where the updatedAt is less than or equal to the specified value.
schema:
format: date-time
type: string
responses:
'200':
description: ''
content:
application/json:
schema:
$ref: '#/components/schemas/CampaignPaginatedResponse'
tags:
- Campaigns
security:
- bearer: []
/campaign/{id}:
get:
operationId: CampaignController_findOne
summary: Get Campaign
parameters:
- name: id
required: true
in: path
description: The unique identifier for the resource.
schema:
format: uuid
type: string
responses:
'200':
description: ''
content:
application/json:
schema:
$ref: '#/components/schemas/Campaign'
tags:
- Campaigns
security:
- bearer: []
patch:
operationId: CampaignController_update
summary: Update Campaign
parameters:
- name: id
required: true
in: path
description: The unique identifier for the resource.
schema:
format: uuid
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateCampaignDTO'
responses:
'200':
description: ''
content:
application/json:
schema:
$ref: '#/components/schemas/Campaign'
tags:
- Campaigns
security:
- bearer: []
delete:
operationId: CampaignController_remove
summary: Delete Campaign
parameters:
- name: id
required: true
in: path
description: The unique identifier for the resource.
schema:
format: uuid
type: string
responses:
'200':
description: ''
content:
application/json:
schema:
$ref: '#/components/schemas/Campaign'
tags:
- Campaigns
security:
- bearer: []
components:
schemas:
SpkiPemPublicKeyConfig:
type: object
properties:
name:
type: string
description: Optional name of the key for identification purposes.
maxLength: 100
format:
type: string
description: The format of the public key.
enum:
- spki-pem
pem:
type: string
description: The PEM-encoded public key.
required:
- format
- pem
CreateTransferCallToolDTO:
type: object
properties:
messages:
type: array
description: 'These are the messages that will be spoken to the user as the tool is running.
For some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.'
items:
oneOf:
- $ref: '#/components/schemas/ToolMessageStart'
title: ToolMessageStart
- $ref: '#/components/schemas/ToolMessageComplete'
title: ToolMessageComplete
- $ref: '#/components/schemas/ToolMessageFailed'
title: ToolMessageFailed
- $ref: '#/components/schemas/ToolMessageDelayed'
title: ToolMessageDelayed
type:
type: string
enum:
- transferCall
destinations:
type: array
description: These are the destinations that the call can be transferred to. If no destinations are provided, server.url will be used to get the transfer destination once the tool is called.
items:
oneOf:
- $ref: '#/components/schemas/TransferDestinationAssistant'
title: Assistant
- $ref: '#/components/schemas/TransferDestinationNumber'
title: Number
- $ref: '#/components/schemas/TransferDestinationSip'
title: Sip
rejectionPlan:
description: "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```"
allOf:
- $ref: '#/components/schemas/ToolRejectionPlan'
required:
- type
ToolParameter:
type: object
properties:
key:
type: string
description: This is the key of the parameter.
value:
description: The value of the parameter. Any JSON type. String values support Liquid templates.
oneOf:
- type: string
- type: number
- type: boolean
- type: object
- type: array
required:
- key
- value
ToolCallHookAction:
type: object
properties:
type:
type: string
description: This is the type of action - must be "tool"
enum:
- tool
tool:
description: This is the tool to call. To use an existing tool, send `toolId` instead.
oneOf:
- $ref: '#/components/schemas/CreateApiRequestToolDTO'
title: ApiRequestTool
- $ref: '#/components/schemas/CreateBashToolDTO'
title: BashTool
- $ref: '#/components/schemas/CreateCodeToolDTO'
title: CodeTool
- $ref: '#/components/schemas/CreateComputerToolDTO'
title: ComputerTool
- $ref: '#/components/schemas/CreateDtmfToolDTO'
title: DtmfTool
- $ref: '#/components/schemas/CreateEndCallToolDTO'
title: EndCallTool
- $ref: '#/components/schemas/CreateFunctionToolDTO'
title: FunctionTool
- $ref: '#/components/schemas/CreateGoHighLevelCalendarAvailabilityToolDTO'
title: GoHighLevelCalendarAvailabilityTool
- $ref: '#/components/schemas/CreateGoHighLevelCalendarEventCreateToolDTO'
title: GoHighLevelCalendarEventCreateTool
- $ref: '#/components/schemas/CreateGoHighLevelContactCreateToolDTO'
title: GoHighLevelContactCreateTool
- $ref: '#/components/schemas/CreateGoHighLevelContactGetToolDTO'
title: GoHighLevelContactGetTool
- $ref: '#/components/schemas/CreateGoogleCalendarCheckAvailabilityToolDTO'
title: GoogleCalendarCheckAvailabilityTool
- $ref: '#/components/schemas/CreateGoogleCalendarCreateEventToolDTO'
title: GoogleCalendarCreateEventTool
- $ref: '#/components/schemas/CreateGoogleSheetsRowAppendToolDTO'
title: GoogleSheetsRowAppendTool
- $ref: '#/components/schemas/CreateHandoffToolDTO'
title: HandoffTool
- $ref: '#/components/schemas/CreateMcpToolDTO'
title: McpTool
- $ref: '#/components/schemas/CreateQueryToolDTO'
title: QueryTool
- $ref: '#/components/schemas/CreateSlackSendMessageToolDTO'
title: SlackSendMessageTool
- $ref: '#/components/schemas/CreateSmsToolDTO'
title: SmsTool
- $ref: '#/components/schemas/CreateTextEditorToolDTO'
title: TextEditorTool
- $ref: '#/components/schemas/CreateTransferCallToolDTO'
title: TransferCallTool
- $ref: '#/components/schemas/CreateSipRequestToolDTO'
title: SipRequestTool
- $ref: '#/components/schemas/CreateVoicemailToolDTO'
title: VoicemailTool
toolId:
type: string
description: This is the tool to call. To use a transient tool, send `tool` instead.
required:
- type
SipTrunkOutboundAuthenticationPlan:
type: object
properties:
authPassword:
type: string
description: This is not returned in the API.
authUsername:
type: string
sipRegisterPlan:
description: This can be used to configure if SIP register is required by the SIP trunk. If not provided, no SIP registration will be attempted.
allOf:
- $ref: '#/components/schemas/SipTrunkOutboundSipRegisterPlan'
CreateCartesiaCredentialDTO:
type: object
properties:
provider:
type: string
enum:
- cartesia
apiKey:
type: string
description: This is not returned in the API.
apiUrl:
type: string
description: This can be used to point to an onprem Cartesia instance. Defaults to api.cartesia.ai.
name:
type: string
description: This is the name of credential. This is just for your reference.
minLength: 1
maxLength: 40
required:
- provider
- apiKey
CallHookAssistantSpeechInterrupted:
type: object
properties:
'on':
type: string
description: This is the event that triggers this hook
enum:
- assistant.speech.interrupted
maxLength: 1000
do:
type: array
description: This is the set of actions to perform when the hook triggers
items:
oneOf:
- $ref: '#/components/schemas/SayHookAction'
title: SayHookAction
- $ref: '#/components/schemas/ToolCallHookAction'
title: ToolCallHookAction
- $ref: '#/components/schemas/MessageAddHookAction'
title: MessageAddHookAction
required:
- 'on'
- do
CustomTranscriber:
type: object
properties:
provider:
type: string
description: This is the transcription provider that will be used. Use `custom-transcriber` for providers that are not natively supported.
enum:
- custom-transcriber
server:
description: "This is where the transcription request will be sent.\n\nUsage:\n1. Vapi will initiate a websocket connection with `server.url`.\n\n2. Vapi will send an initial text frame with the sample rate. Format:\n```\n {\n \"type\": \"start\",\n \"encoding\": \"linear16\", // 16-bit raw PCM format\n \"container\": \"raw\",\n \"sampleRate\": {{sampleRate}},\n \"channels\": 2 // customer is channel 0, assistant is channel 1\n }\n```\n\n3. Vapi will send the audio data in 16-bit raw PCM format as binary frames.\n\n4. You can read the messages something like this:\n```\nws.on('message', (data, isBinary) => {\n if (isBinary) {\n pcmBuffer = Buffer.concat([pcmBuffer, data]);\n console.log(`Received PCM data, buffer size: ${pcmBuffer.length}`);\n } else {\n console.log('Received message:', JSON.parse(data.toString()));\n }\n});\n```\n\n5. You will respond with transcriptions as you have them. Format:\n```\n {\n \"type\": \"transcriber-response\",\n \"transcription\": \"Hello, world!\",\n \"channel\": \"customer\" | \"assistant\"\n }\n```"
allOf:
- $ref: '#/components/schemas/Server'
fallbackPlan:
description: This is the plan for transcriber provider fallbacks in the event that the primary transcriber provider fails.
allOf:
- $ref: '#/components/schemas/FallbackTranscriberPlan'
required:
- provider
- server
CreateAnthropicCredentialDTO:
type: object
properties:
provider:
type: string
enum:
- anthropic
apiKey:
type: string
maxLength: 10000
description: This is not returned in the API.
name:
type: string
description: This is the name of credential. This is just for your reference.
minLength: 1
maxLength: 40
required:
- provider
- apiKey
CreateRunpodCredentialDTO:
type: object
properties:
provider:
type: string
enum:
- runpod
apiKey:
type: string
description: This is not returned in the API.
name:
type: string
description: This is the name of credential. This is just for your reference.
minLength: 1
maxLength: 40
required:
- provider
- apiKey
OpenAIFunction:
type: object
properties:
strict:
type: boolean
description: 'This is a boolean that controls whether to enable strict schema adherence when generating the function call. If set to true, the model will follow the exact schema defined in the parameters field. Only a subset of JSON Schema is supported when strict is true. Learn more about Structured Outputs in the [OpenAI guide](https://openai.com/index/introducing-structured-outputs-in-the-api/).
@default false'
default: false
name:
type: string
description: 'This is the the name of the function to be called.
Must be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length of 64.'
maxLength: 64
pattern: /^[a-zA-Z0-9_-]{1,64}$/
description:
type: string
description: This is the description of what the function does, used by the AI to choose when and how to call the function.
parameters:
description: 'These are the parameters the functions accepts, described as a JSON Schema object.
See the [OpenAI guide](https://platform.openai.com/docs/guides/function-calling) for examples, and the [JSON Schema reference](https://json-schema.org/understanding-json-schema) for documentation about the format.
Omitting parameters defines a function with an empty parameter list.'
allOf:
- $ref: '#/components/schemas/OpenAIFunctionParameters'
required:
- name
SonioxContextGeneralItem:
type: object
properties:
key:
type: string
description: The key describing the type of context (e.g., "domain", "topic", "doctor", "organization").
minLength: 1
example: domain
value:
type: string
description: The value for the context key (e.g., "Healthcare", "Diabetes management consultation").
minLength: 1
example: Healthcare
required:
- key
- value
FormatPlan:
type: object
properties:
enabled:
type: boolean
description: 'This determines whether the chunk is formatted before being sent to the voice provider. This helps with enunciation. This includes phone numbers, emails and addresses. Default `true`.
Usage:
- To rely on the voice provider''s formatting logic, set this to `false`.
If `voice.chunkPlan.enabled` is `false`, this is automatically `false` since there''s no chunk to format.
@default true'
example: true
numberToDigitsCutoff:
type: number
description: 'This is the cutoff after which a number is converted to individual digits instead of being spoken as words.
Example:
- If cutoff 2025, "12345" is converted to "1 2 3 4 5" while "1200" is converted to "twelve hundred".
Usage:
- If your use case doesn''t involve IDs like zip codes, set this to a high value.
- If your use case involves IDs that are shorter than 5 digits, set this to a lower value.
@default 2025'
minimum: 0
example: 2025
replacements:
type: array
description: 'These are the custom replacements you can make to the chunk before it is sent to the voice provider.
Usage:
- To replace a specific word or phrase with a different word or phrase, use the `ExactReplacement` type. Eg. `{ type: ''exact'', key: ''hello'', value: ''hi'' }`
- To replace a word or phrase that matches a pattern, use the `RegexReplacement` type. Eg. `{ type: ''regex'', regex: ''\\b[a-zA-Z]{5}\\b'', value: ''hi'' }`
@default []'
items:
oneOf:
- $ref: '#/components/schemas/ExactReplacement'
title: ExactReplacement
- $ref: '#/components/schemas/RegexReplacement'
title: RegexReplacement
formattersEnabled:
type: array
description: 'List of formatters to apply. If not provided, all default formatters will be applied.
If provided, only the specified formatters will be applied.
Note: Some essential formatters like angle bracket removal will always be applied.
@default undefined'
enum:
- markdown
- asterisk
- quote
- dash
- newline
- colon
- acronym
- dollarAmount
- email
- date
- time
- distance
- unit
- percentage
- phoneNumber
- number
- stripAsterisk
items:
type: string
enum:
- markdown
- asterisk
- quote
- dash
- newline
- colon
- acronym
- dollarAmount
- email
- date
- time
- distance
- unit
- percentage
- phoneNumber
- number
- stripAsterisk
SecurityFilterPlan:
type: object
properties:
enabled:
type: boolean
description: 'Whether the security filter is enabled.
@default false'
default: false
filters:
description: 'Array of security filter types to apply.
If array is not empty, only those security filters are run.'
example: '[{ type: "sql-injection" }, { type: "xss" }]'
type: array
items:
$ref: '#/components/schemas/SecurityFilterBase'
mode:
type: string
description: 'Mode of operation when a security threat is detected.
- ''sanitize'': Remove or replace the threatening content
- ''reject'': Replace the entire transcript with replacement text
- ''replace'': Replace threatening patterns with replacement text
@default ''sanitize'''
enum:
- sanitize
- reject
- replace
default: sanitize
replacementText:
type: string
description: 'Text to use when replacing filtered content.
@default ''[FILTERED]'''
default: '[FILTERED]'
GoogleVoicemailDetectionPlan:
type: object
properties:
beepMaxAwaitSeconds:
type: number
description: 'This is the maximum duration from the start of the call that we will wait for a voicemail beep, before speaking our message
- If we detect a voicemail beep before this, we will speak the message at that point.
- Setting too low a value means that the bot will start speaking its voicemail message too early. If it does so before the actual beep, it will get cut off. You should definitely tune this to your use case.
@default 30
@min 0
@max 60'
minimum: 0
maximum: 30
default: 30
provider:
type: string
description: This is the provider to use for voicemail detection.
enum:
- google
backoffPlan:
description: This is the backoff plan for the voicemail detection.
allOf:
- $ref: '#/components/schemas/VoicemailDetectionBackoffPlan'
type:
type: string
description: 'This is the detection type to use for voicemail detection.
- ''audio'': Uses native audio models (default)
- ''transcript'': Uses ASR/transcript-based detection
@default ''audio'' (audio detection)'
enum:
- audio
- transcript
required:
- provider
LangfuseObservabilityPlan:
type: object
properties:
provider:
type: string
enum:
- langfuse
promptName:
type: string
description: The name of a Langfuse prompt to link generations to. This enables tracking which prompt version was used for each generation. https://langfuse.com/docs/prompt-management/features/link-to-traces
promptVersion:
type: number
description: The version number of the Langfuse prompt to link generations to. Used together with promptName to identify the exact prompt version. https://langfuse.com/docs/prompt-management/features/link-to-traces
minimum: 1
traceName:
type: string
description: 'Custom name for the Langfuse trace. Supports Liquid templates.
Available variables:
- {{ call.id }} - Call UUID
- {{ call.type }} - ''inboundPhoneCall'', ''outboundPhoneCall'', ''webCall''
- {{ assistant.name }} - Assistant name
- {{ assistant.id }} - Assistant ID
Example: "{{ assistant.name }} - {{ call.type }}"
Defaults to call ID if not provided.'
tags:
description: This is an array of tags to be added to the Langfuse trace. Tags allow you to categorize and filter traces. https://langfuse.com/docs/tracing-features/tags
type: array
items:
type: string
metadata:
type: object
description: 'This is a JSON object that will be added to the Langfuse trace. Traces can be enriched with metadata to better understand your users, application, and experiments. https://langfuse.com/docs/tracing-features/metadata
By default it includes the call metadata, assistant metadata, and assistant overrides.'
required:
- provider
- tags
ElevenLabsTranscriber:
type: object
properties:
provider:
type: string
description: This is the transcription provider that will be used.
enum:
- 11labs
model:
description: This is the model that will be used for the transcription.
oneOf:
- type: string
enum:
- scribe_v1
- scribe_v2
- scribe_v2_realtime
language:
type: string
description: This is the language that will be used for the transcription.
enum:
- aa
- ab
- ae
- af
- ak
- am
- an
- ar
- as
- av
- ay
- az
- ba
- be
- bg
- bh
- bi
- bm
- bn
- bo
- br
- bs
- ca
- ce
- ch
- co
- cr
- cs
- cu
- cv
- cy
- da
- de
- dv
- dz
- ee
- el
- en
- eo
- es
- et
- eu
- fa
- ff
- fi
- fj
- fo
- fr
- fy
- ga
- gd
- gl
- gn
- gu
- gv
- ha
- he
- hi
- ho
- hr
- ht
- hu
- hy
- hz
- ia
- id
- ie
- ig
- ii
- ik
- io
- is
- it
- iu
- ja
- jv
- ka
- kg
- ki
- kj
- kk
- kl
- km
- kn
- ko
- kr
- ks
- ku
- kv
- kw
- ky
- la
- lb
- lg
- li
- ln
- lo
- lt
- lu
- lv
- mg
- mh
- mi
- mk
- ml
- mn
- mr
- ms
- mt
- my
- na
- nb
- nd
- ne
- ng
- nl
- nn
- 'no'
- nr
- nv
- ny
- oc
- oj
- om
- or
- os
- pa
- pi
- pl
- ps
- pt
- qu
- rm
- rn
- ro
- ru
- rw
- sa
- sc
- sd
- se
- sg
- si
- sk
- sl
- sm
- sn
- so
- sq
- sr
- ss
- st
- su
- sv
- sw
- ta
- te
- tg
- th
- ti
- tk
- tl
- tn
- to
- tr
- ts
- tt
- tw
- ty
- ug
- uk
- ur
- uz
- ve
- vi
- vo
- wa
- wo
- xh
- yi
- yue
- yo
- za
- zh
- zu
silenceThresholdSeconds:
type: number
description: This is the number of seconds of silence before VAD commits (0.3-3.0).
minimum: 0.3
maximum: 3
example: 1.5
confidenceThreshold:
type: number
description: This is the VAD sensitivity (0.1-0.9, lower indicates more sensitive).
minimum: 0.1
maximum: 0.9
example: 0.4
minSpeechDurationMs:
type: number
description: This is the minimum speech duration for VAD (50-2000ms).
minimum: 50
maximum: 2000
example: 100
minSilenceDurationMs:
type: number
description: This is the minimum silence duration for VAD (50-2000ms).
minimum: 50
maximum: 2000
example: 100
fallbackPlan:
description: This is the plan for transcriber provider fallbacks in the event that the primary transcriber provider fails.
allOf:
- $ref: '#/components/schemas/FallbackTranscriberPlan'
required:
- provider
ToolMessageDelayed:
type: object
proper
# --- truncated at 32 KB (715 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/vapi-ai/refs/heads/main/openapi/vapi-ai-campaigns-api-openapi.yml