Skip to content

XML Descriptions for Integration Template

When you build a custom CRM or Helpdesk integration for Cloud Voice, you describe it in an XML template. The template declares the connection details the phone system needs, API endpoints, data fields, authentication, and the functional scenarios that drive each integration feature. This page documents every element, attribute, and variable you can use in that template.

Templates conform to the XML 1.1 specification. The sections below explain the variable, function, and element syntax you will work with throughout a template.

A template can reference variables so that data is resolved dynamically. Each variable is replaced with its actual value when Cloud Voice runs the template.

Variable values come from three places:

  • Predefined variables supplied by Cloud Voice.

  • Parameter values a user enters while configuring the integration.

  • Values extracted from an API response. You pull a value out of the response body with a JSON path, for example:

    <Output Name="UserUniqueId" Path="data.#.id"></Output>

    To pull the first value that meets a condition:

    <Output Name="BusinessNumber2" Path="identities.#(type==&quot;phone_number&quot;)#|1.value"></Output>

Variables are referenced using Go’s text/template syntax:

FormExample
Standard variable{{.varname}}
Conditional variable{{ if .varname }} Welcome, member! {{ else }} Please sign up. {{ end }}
Function call on a variable{{ Capitalize .varname }}

Functions transform or format a variable’s value inline. The following functions are available.

FunctionPurpose and example
TimeFormatFormats a timestamp.
Format: {{ TimeFormat Timestamp_variable "format_string" "convert_to_UTC" }}
Example: {{ TimeFormat .StartTimeUnix "yyyy-MM-ddTHH:mm:ss.000Zz" "1" }}. If .StartTimeUnix is 1672531199, the result is 2023-01-01T00:59:59.000Z.
ToMillisConverts a seconds timestamp to milliseconds.
Format: {{ ToMillis Timestamp_variable }}
Example: {{ ToMillis .StartTimeUnix }}. If .StartTimeUnix is 1672531199, the result is 1672531199000.
CapitalizeCapitalizes the first letter of a string.
Format: {{ Capitalize variable_string }}
Example: if the value is hello world, the result is Hello world.
UrlEncodeURL-encodes a string (replaces spaces and other reserved characters with percent-escapes so the value is safe inside a URL).
Format: {{ UrlEncode .variable }}
Example: if the value is hello world!, the result is hello%20world%21.
ToMinutesConverts an hh:mm:ss duration to a total number of minutes.
Format: {{ ToMinutes duration_variable }}
Example: {{ ToMinutes .ChatDuration }} (used in the Chat journal scenario).
TsSecToMilliSecConverts a seconds timestamp to a milliseconds timestamp (same result as ToMillis).
Format: {{ TsSecToMilliSec Timestamp_variable }}
Example: {{ TsSecToMilliSec .EndTimeUnix }} (used in the Chat journal scenario).

These are the main building blocks of a template. Together they define how Cloud Voice connects to the third-party system and processes the data each feature needs.

The overall structure looks like this:

<Information>
<Scenarios>
<Scenario Id="1" Type="REST">
<Parameters>
<Parameter Name="example" Value="example"></Parameter>
...
</Parameters>
<Requests>
<Request Name="ExampleRequest" Method="GET" URL="https://api.example.com/getuser">
<Outputs>
<Output Name="ContactId" Path="data.#.id" Type="string"></Output>
...
</Outputs>
</Request>
</Requests>
</Scenario>
</Scenarios>
</Information>
ElementDescription
<Information>The root element. Its attributes carry the template’s basic information and configuration overview (see Template property), and it holds the <Scenarios> child that defines each integration capability.
<Scenarios>A collection of <Scenario> elements. Each scenario holds children such as <Parameters>, <Requests>, and <Outputs> that describe one functional capability. Cloud Voice loads the configured scenarios and runs the HTTP requests or operations they define. Supported scenarios: Authentication, User association, Automatic contact synchronization, Automatic contact creation, Automatic ticket creation (Helpdesk only), Call journal, and Chat journal.
<Parameters>A collection of parameters tied to a scenario or request, dynamic values or configuration settings needed to run it. Depending on the case, they are passed in the request URL, body, or headers.
<Requests>A collection of requests a scenario issues to implement its feature.
<Outputs>A list of <Output> elements that define which fields to extract from the API response.

The <Information> element’s attributes describe the template as a whole.

AttributeDescription
ProviderTemplate type. Fixed as crm or helpdesk.
NameTemplate name.
KeyUnique identifier for the template.
LogoFilename of the logo.
RemarkA description or note about the template.
VersionTemplate version, for example 1.0.0.
AuthTypeAuthentication method: none, basic, oauth2, or bearertoken.
MaxConcurrentRequestMaximum number of concurrent HTTP requests allowed to the CRM/Helpdesk.
UserAssociationWhether user association is enabled. 0 disabled, 1 enabled.
CallJournalWhether call journaling is enabled. 0 disabled, 1 enabled.
CreateNewContactWhether automatic contact creation is enabled. 0 disabled, 1 enabled.
CreateNewTicketWhether automatic ticket creation is enabled. 0 disabled, 1 enabled.
ChatJournalWhether chat journaling is enabled. 0 disabled, 1 enabled.

This scenario defines how Cloud Voice authenticates to the CRM/Helpdesk.

<Scenario Id="AuthMethod" Type="AUTH">
<Presets></Presets>
<Parameters>
<Parameter Name="AuthMethod" Value="oauth2"></Parameter>
<Parameter Name="AuthEndPoint" Value="https://api.example.com/oauth/v2/auth?client_id={{.client_id}}"></Parameter>
<Parameter Name="TokenEndPoint" Value="https://api.example.com/oauth/v2/token?client_id={{.client_id}}&amp;client_secret={{.client_secret}}"></Parameter>
<Parameter Name="ContentType" Value="application/json"></Parameter>
<Parameter Name="AdditionalQueryString"></Parameter>
<Parameter Name="Scope" Value="contacts.read,contacts.write,calls.read,calls.write,user.read,user.write"></Parameter>
<Parameter Name="CredentialType"></Parameter>
<Parameter Name="Base64EncodedCredential"></Parameter>
<Parameter Name="TokenRefreshInterval" Value="25"></Parameter>
<Parameter Name="TokenRefreshBody" Value="grant_type=refresh_token&amp;refresh_token={{.refresh_token}}"></Parameter>
<Parameter Name="TokenRefreshEndpointMethod" Value="post"></Parameter>
<Parameter Name="TokenRefreshEndpoint" Value="https://api.example.com/oauth2/token"></Parameter>
<Parameter Name="TokenRefreshContentType" Value="application/x-www-form-urlencoded"></Parameter>
<Parameter Father="CustomFieldList" Name="client_id" Editor="password" Title="Client ID" Value="" IsDelete="0" IsRequired="1"></Parameter>
<Parameter Father="CustomFieldList" Name="client_secret" Editor="password" Title="Client Secret" Value="" IsDelete="0" IsRequired="1"></Parameter>
<Parameter Father="CustomFieldList" Name="application_id" Editor="string" Title="Application ID" Value="" IsDelete="0" IsRequired="1"></Parameter>
<Parameter Father="CustomFieldList" Name="server_address" Editor="string" Title="Server Address" Value="" IsDelete="0" IsRequired="1"></Parameter>
<Parameter Father="PopulateTemplateString" Name="Content-Type" Type="Header" Value="application/json" Description="The format of the request body"/>
<Parameter Father="PopulateTemplateString" Name="Accept" Type="Header" Value="application/json" Description="The expected response data format from the server"/>
<Parameter Father="PopulateTemplateString" Name="X-CSRF-Token" Type="Header" Value="f3e1a2b4c5d6e7f8g9h0" Description="Prevent Cross-Site Request Forgery (CSRF) attacks"/>
<Parameter Father="PopulateTemplateString" Name="X-Client-Id" Type="Header" Value="{{.client_id}}" Description="for client identification"/>
<Parameter Father="FollowUpList" Name="ffb425cb-565d-49cd-92be-3290d0ab5129" Type="FollowUpRequest" Value="" IsDelete="0">
<Parameter Name="TriggeredEvent" Value="token_retrieved"></Parameter>
<Parameter Name="RequestMethod" Value="post"></Parameter>
<Parameter Name="Url" Value="https://api.example.com/v1/install/verify"></Parameter>
<Parameter Name="Headers" Value="{&quot;Content-Type&quot;:&quot;application/json&quot;,&quot;X-Request-ID&quot;:&quot;550e8400-e29b-41d4-a716-446655440000&quot;,&quot;User-Agent&quot;:&quot;YourApp-Integration/1.0.0&quot;}"></Parameter>
<Parameter Name="Body" Value="{&quot;app_id&quot;:&quot;your_unique_app_identifier&quot;,&quot;webhook_url&quot;:&quot;https://your-app.com/api/webhooks&quot;}"></Parameter>
<Parameter Name="ResponseFieldPath" Value=".data.access_token, .tokens[0].value"></Parameter>
<Parameter Name="TargetVariable" Value="token,refresh"></Parameter>
</Parameter>
<Parameter Name="AuthMode" Value="pkce"></Parameter>
<Parameter Name="CodeChallengeMethod" Value="S256"></Parameter>
<Parameter Name="EnableKeepalive" Value="1"></Parameter>
<Parameter Name="KeepaliveInterval" Value="5"></Parameter>
</Parameters>
<Requests></Requests>
</Scenario>
AttributeDescription
IdScenario identifier. Fixed as AuthMethod.
TypeScenario type. AUTH, the scenario performs authentication.
AttributeDescription
NameName of the authentication setting (see Authentication settings).
ValueValue of the authentication setting.
FatherThe parent parameter that groups related child parameters. The authentication scenario has three parent types: CustomFieldList, PopulateTemplateString, and FollowUpList.

The three parent parameters act as containers that organize child parameters into setting groups:

  • CustomFieldList, Defines the fields users fill in with their authentication credentials (Client ID, Client Secret, and so on) in the configuration UI.

  • PopulateTemplateString, Defines custom HTTP headers to attach to every predefined CRM/Helpdesk request (user association, contact synchronization, and so on).

  • FollowUpList, Defines one or more automated requests that fire after a specific event, such as after a token is retrieved.

CustomFieldList (authentication credential inputs):

AttributeDescription
NameVariable name of the field, usable in the template. For example, client_id is referenced as {{.client_id}}.
EditorField type: string (plain text), password (masked input), or list (selectable options).
TitleLabel shown above the field in the configuration UI.
ValueThe predefined list of options. Available only when Editor is list. Separate options with commas, for example option1,option2.
IsRequiredWhether the field is mandatory: 0 optional, 1 required. Available only when AuthMethod is oauth2.

PopulateTemplateString (custom HTTP headers):

AttributeDescription
TypeParameter type. Fixed as Header.
NameName of the custom header.
ValueHeader value, a literal value or a variable. You can reference an authentication field variable, for example {{.client_id}}.
DescriptionA short note describing the header’s purpose.

FollowUpList (follow-up requests):

AttributeDescription
TypeParameter type. Fixed as FollowUpRequest.
NameFor the parent parameter, the system generates an ID automatically. For child parameters, the name of the follow-up request setting (see Follow-up request settings).
ValueValue of the follow-up request setting.
SettingDescription
AuthMethodAuthentication method. none, no authentication, or only relevant variables (an API key, a webhook URL) are exchanged. basic, credentials such as a username/password or API key are base64-encoded and sent in a header on every request. oauth2, tokens grant access without sharing credentials; the header and other parameters (such as the access token) are obtained through specific API requests. bearertoken, every request carries a header of the form Authorization: Bearer {{.AccessToken}}, where {{.AccessToken}} is the token granted by the CRM/Helpdesk.
AuthModeAuthorization mode (OAuth2 only). authorization_code, the standard code flow; use it when the CRM/Helpdesk expects a client_secret. pkce, Authorization Code with PKCE; use it when PKCE is supported, for an extra layer of security. In PKCE mode Cloud Voice generates a code_verifier, hashes it with SHA256 and Base64URL-encodes it into a code_challenge, sends the challenge upfront, and later presents the original verifier during token exchange. The server hashes the submitted verifier and compares it to the stored challenge; a match proves the client holds the original verifier, which prevents interception attacks.
AuthEndPointAuthorization URL to open to start the authorization process (OAuth2 only).
TokenEndPointAPI URL for obtaining the access token and refresh token (OAuth2 and bearer token only).
ContentTypeContent type of the token retrieval request: application/json or application/x-www-form-urlencoded.
CodeChallengeMethodHow the code_verifier is transformed into the code_challenge (available only when AuthMode is pkce). S256, SHA256 hash + Base64URL encoding (recommended). plain, use the verifier directly, for systems that do not support SHA256.
AdditionalQueryStringQuery variables to add when the CRM/Helpdesk authenticates with query parameters instead of a scope (OAuth2 only).
ScopeThe scope of CRM/Helpdesk data Cloud Voice may access (OAuth2 only).
CredentialTypeCredential type (Basic only): username_password or api_key.
Base64EncodedCredentialThe combination format used to build the basic authentication string (Basic only), for example {{.username}}:{{.password}} or {{.api_key}}.
TokenRefreshEndpointMethodHTTP method for the token refresh API: get or post (OAuth2 and bearer token only).
TokenRefreshEndpointAPI URL for refreshing the access token (OAuth2 and bearer token only).
TokenRefreshContentTypeContent type of the refresh request: application/json, application/x-www-form-urlencoded, or multipart/form-data (OAuth2 and bearer token only).
TokenRefreshIntervalHow often the token is refreshed automatically, in minutes (OAuth2 and bearer token only).
TokenRefreshBodyRequest body for the refresh API (OAuth2 and bearer token only).
EnableKeepaliveWhether to keep the connection alive: 0 disabled, 1 enabled (keep-alive requests are sent at the configured interval).
KeepaliveIntervalInterval for keep-alive requests, in minutes.
SettingDescription
TriggeredEventThe event that fires the request. token_retrieved, after an access token is retrieved. token_refreshed, after an access token is refreshed.
RequestMethodHTTP method: get or post.
UrlEndpoint URL for the follow-up operation, for example https://api.example.com/rest-services/login.
HeadersRequest headers in JSON. Use {{.varname}} for dynamic values, for example {"Content-Type":"application/json", "X-Custom-Header": "{{.DynamicValue}}"}.
BodyRequest payload in JSON. Use {{.varname}} for dynamic values, for example {"lastName":"{{.LastName}}","ownerId":"{{.Id}}","phone":"{{.BusinessNumber}}"}.
ResponseFieldPathJSON path(s) to extract from the response. Separate multiple paths with commas, for example .data.access_token, .tokens[0].value.
TargetVariableNames of the system variables that store the extracted values. These can be existing or new custom variables and are stored globally for use across the integration. Separate multiple names with commas, for example token,refresh. Values are assigned in the same order as the paths in ResponseFieldPath.

This scenario retrieves the list of users from the CRM/Helpdesk.

<Scenario Id="UserAssociation" Type="REST">
<Parameters></Parameters>
<Requests>
<Request Name="UserAssociation" Method="GET" ResponseType="application/json" RequestEncoding="" URLFormat="https://www.api.example.com/v1/users?type=ActiveUsers">
<Parameters>
<Parameter Name="PaginationEnabled" Value="0" />
<Parameter Name="PaginationType" Value="" />
<Parameter Name="VarPageName" Value="page" />
<Parameter Name="VarPageValue" Value="1" />
<Parameter Name="VarPageSizeName" Value="page_size" />
<Parameter Name="VarPageSizeValue" Value="10" />
<Parameter Name="VarOffsetName" Value="from" />
<Parameter Name="VarOffsetValue" Value="1" />
<Parameter Name="VarLimitName" Value="limit" />
<Parameter Name="VarLimitValue" Value="10" />
<Parameter Name="VarNextPagePath" Value="links.next" />
</Parameters>
<Outputs>
<Output Name="UserUniqueId" Path="users.#.id" Type=""></Output>
<Output Name="FirstName" Path="users.#.First_Name" Type=""></Output>
<Output Name="LastName" Path="users.#.Last_Name" Type=""></Output>
<Output Name="Email" Path="users.#.Email" Type=""></Output>
</Outputs>
</Request>
</Requests>
</Scenario>
AttributeDescription
IdScenario identifier. Fixed as UserAssociation.
TypeScenario type. REST, the scenario runs a REST API through an HTTP request.
AttributeDescription
NameRequest name, used to identify the request within the scenario. Fixed as UserAssociation.
MethodHTTP method. Defaults to GET; change it if needed.
ResponseTypeExpected response format, in JSON (application/json).
RequestEncodingHow the request is encoded. Empty in this scenario.
URLFormatRequest URL of the API endpoint.

The <Parameter> element sets pagination behavior with a Name (a pagination setting) and its Value.

SettingDescription
PaginationEnabledWhether pagination is enabled: 0 disable, 1 enable.
PaginationTypePagination mode. page_based, by page number and page size. offset_based, by starting index and record limit. link_based, by following the next-page URL in the response.
VarPageNameParameter name that specifies the page number (page-based only).
VarPageValueInitial page number to query from (page-based only).
VarPageSizeNameParameter name that specifies records per page (page-based only).
VarPageSizeValueMaximum records to return per page (page-based only).
VarOffsetNameParameter name that specifies the start position (offset-based only).
VarOffsetValueStarting position, as the number of records to skip (offset-based only). For example, 1 starts at the first record; 100 starts at the 100th.
VarLimitNameParameter name that specifies records per page (offset-based only).
VarLimitValueMaximum records to return per page (offset-based only).
VarNextPagePathJSON path (for example links.next) to the next-page link (link-based only).
AttributeDescription
NameOutput variable name, the value to retrieve from the response.
PathLocation of the field in the response, using path syntax for nested data (for example users.#.id).
TypeData type of the output variable. Fixed as string.

The scenario retrieves these variables:

VariableDescription
UserUniqueIdUnique ID of the CRM/Helpdesk user.
FirstNameUser’s first name.
LastNameUser’s last name.
EmailUser’s email.

Automatic contact synchronization scenario

Section titled “Automatic contact synchronization scenario”

This scenario searches for contacts in the CRM/Helpdesk. Its results drive contact search, automatic contact synchronization, and the call pop-up.

<Scenario Id="SyncContactAuto" Type="REST">
<Presets></Presets>
<Parameters>
<Parameter Name="ContactUrlType" Value="retrieve_from_contact"></Parameter>
<Parameter Name="URLFormat"></Parameter>
<Parameter Name="ContactFieldForUri" Value="data.#.contactUrl"></Parameter>
<Parameter Name="ContactsIdEnable" Value="1"></Parameter>
<Parameter Name="FirstNameEnable" Value="1"></Parameter>
<Parameter Name="BusinessNumberEnable" Value="1"></Parameter>
<Parameter Name="CustomValueEnable" Value="0"></Parameter>
</Parameters>
<Requests>
<Request Name="Contacts" Method="GET" ResponseType="application/json" RequestEncoding="" URLFormat="https://www.api.example.com/v1/Contacts/search?criteria=((Phone:equals:{{.Phone}})or(Home_Phone:equals:{{.Phone}})or(Mobile:equals:{{.Phone}})or(Asst_Phone:equals:{{.Phone}}))">
<Parameters></Parameters>
<Outputs>
<Output Name="ContactsId" Path="data.0.id" Type=""></Output>
<Output Name="FirstName" Path="data.0.First_Name" Type=""></Output>
<Output Name="BusinessNumber" Path="data.0.Phone" Type=""></Output>
...
<Output Name="CustomValue" Path="data.0.Owner" Type=""></Output>
</Outputs>
</Request>
</Requests>
</Scenario>
AttributeDescription
IdScenario identifier. Fixed as SyncContactAuto.
TypeScenario type. REST, the scenario runs a REST API through an HTTP request.

The <Parameter> element carries the scenario’s configuration settings as Name/Value pairs.

SettingDescription
ContactUrlTypeHow the contact URL for the call pop-up is obtained. specify_url_format, build the URL from a format string with variables. retrieve_from_contact, pull the URL directly from a field in the contact search response.
URLFormatThe expression for the contact URL. You can use variables captured during the authentication process, plus ContactSyncType (contact type, taken from the search request’s name), ContactId, and CustomValue (both retrieved from this scenario’s response). For example: {{.crm_url}}/crm/{{.CustomValue}}/tab/{{Capitalize .ContactSyncType}}/{{.ContactId}}. If the provided variables are not enough, define extra requests to retrieve what you need (see Retrieve additional variables for global use).
ContactFieldForUriJSON path to the contact URL field in the response, for example .data.#.contactUrl.
ContactsIdEnableWhether to retrieve the contact’s ID. Set to 1 (required).
FirstNameEnableWhether to retrieve the contact’s first name. Set to 1 (required).
BusinessNumberEnableWhether to retrieve the contact’s business phone number: 0 no, 1 yes. At least one phone number is required.
CustomValueEnableWhether to enable a custom variable that can be used to build the contact URL: 0 disable, 1 enable.

The remaining fields are optional retrieval toggles. Each takes 0 (do not retrieve) or 1 (retrieve):

SettingRetrieves
LastNameEnableContact’s last name
CompanyEnableContact’s company
EmailEnableContact’s email
BusinessNumber2EnableSecond business phone number
BusinessFaxNumberEnableBusiness fax number
MobileNumberEnableMobile number
MobileNumber2EnableSecond mobile number
HomeNumberEnableHome number
HomeNumber2EnableSecond home number
HomeFaxNumberEnableHome fax number
OtherNumberEnableOther number (not business or home)
ZipCodeEnableZip code
StreetEnableStreet
CityEnableCity
StateEnableState/province
CountryEnableCountry
RemarkEnableRemark
AttributeDescription
NameRequest name. Set it to the actual name of the contact type being searched in the CRM/Helpdesk; it is exposed as the ContactSyncType variable.
MethodHTTP method. Defaults to GET; change it if needed.
ResponseTypeExpected response format, in JSON (application/json).
RequestEncodingHow the request is encoded. Empty in this scenario.
URLFormatRequest URL of the API endpoint.

Each <Output> uses Name, Path, and Type (fixed as string), as described under User association.

VariableDescription
ContactsId(Required) Unique ID of the contact.
FirstName(Required) Contact’s first name.
LastNameContact’s last name.
CompanyContact’s company.
EmailContact’s email.
BusinessNumberBusiness phone number. At least one phone number is required.
BusinessNumber2Second business phone number.
BusinessFaxNumberBusiness fax number.
MobileNumberMobile number.
MobileNumber2Second mobile number.
HomeNumberHome number.
HomeNumber2Second home number.
HomeFaxNumberHome fax number.
OtherNumberOther phone number.
ZipCodeZip code.
StreetStreet.
CityCity.
StateState or province.
CountryCountry.
RemarkRemark.
CustomValueCustom variable used to build the contact URL.

This scenario creates a new contact in the CRM/Helpdesk when a caller’s number does not match any existing contact.

<Scenario Id="CreateNewContact" Type="REST">
<Parameters></Parameters>
<Requests>
<Request Name="Contacts" Method="POST" ResponseType="application/json" RequestEncoding="" URLFormat="https://www.api.example.com/v1/Contacts">
<Parameters>
<Parameter Name="Data" Type="Body" Value="{&quot;data&quot;: [{&quot;Last_Name&quot;:&quot;{{.LastName}}&quot;,&quot;First_Name&quot;:&quot;{{.FirstName}}&quot;,&quot;Phone&quot;:&quot;{{.BusinessNumber}}&quot;}]}"></Parameter>
</Parameters>
<Outputs></Outputs>
</Request>
</Requests>
</Scenario>
AttributeDescription
IdScenario identifier. Fixed as CreateNewContact.
TypeScenario type. REST, the scenario runs a REST API through an HTTP request.
AttributeDescription
NameRequest name. Set it to the actual name of the contact type to create in the CRM/Helpdesk.
MethodHTTP method. POST in this scenario.
ResponseTypeExpected response format, in JSON (application/json).
RequestEncodingHow the request is encoded. Empty in this scenario.
URLFormatRequest URL of the API endpoint.

The <Parameter> nested inside <Request> defines the request body.

AttributeDescription
NameParameter name. Fixed as Data.
TypeParameter type. Fixed as Body.
ValueThe parameters passed in the request body, inside a data structure. Values can come from Cloud Voice’s predefined variables.

Only the required variables appear below. For more, see Retrieve additional variables for global use.

VariableDescription
Variables from the AuthMethod scenarioVariables captured from the authentication credential inputs during authentication.
Target variables from follow-up requestsValues extracted from the responses of follow-up requests.
{{.LastName}}Contact’s last name.
{{.FirstName}}Contact’s first name.
{{.BusinessNumber}}Contact’s phone number.

Automatic ticket creation scenario (Helpdesk only)

Section titled “Automatic ticket creation scenario (Helpdesk only)”

This scenario creates a new ticket in the Helpdesk.

<Scenario Id="CreateNewTicket" Type="REST">
<Presets></Presets>
<Parameters>
<Parameter Name="EnableSubject" Value="1"></Parameter>
<Parameter Name="Subject" Value="{{.Communication_Type}} {{.Call_Status}} - from {{.Call_From}} to {{.Call_To}}"></Parameter>
<Parameter Name="EnableDescription" Value="1"></Parameter>
<Parameter Name="Description" Value="{{.Time}} {{.Communication_Type}} {{.Call_Status}} - from {{.Call_From}} to {{.Call_To}} {{.Talk_Duration}}"></Parameter>
</Parameters>
<Requests>
<Request Name="CreateNewTicket" Method="POST" Weight="0" ResponseType="application/json" RequestEncoding="" URLFormat="https://{{.domain}}/api/v1/tickets">
<Parameters>
<Parameter Name="Data" Type="Body" Value="{&quot;subject&quot;:&quot;{{.Subject}}&quot;,&quot;contactId&quot;:&quot;{{.ContactId}}&quot;,&quot;phone&quot;:&quot;{{.ContactNumber}}&quot;,&quot;description&quot;:&quot;{{.Description}}&quot;}"></Parameter>
</Parameters>
<Outputs></Outputs>
</Request>
</Requests>
</Scenario>
AttributeDescription
IdScenario identifier. Fixed as CreateNewTicket.
TypeScenario type. REST, the scenario runs a REST API through an HTTP request.

Configuration settings for the scenario, as Name/Value pairs:

SettingDescription
EnableSubjectWhether the ticket subject is customizable: 0 disable, 1 enable.
SubjectDefault subject value. Default: {{.Communication_Type}} {{.Call_Status}} - from {{.Call_From}} to {{.Call_To}}. See the variable list for supported variables.
EnableDescriptionWhether the ticket description is customizable: 0 disable, 1 enable.
DescriptionDefault description value. Default: {{.Time}} {{.Communication_Type}} {{.Call_Status}} - from {{.Call_From}} to {{.Call_To}} {{.Talk_Duration}}. See the variable list for supported variables.
AttributeDescription
NameRequest name. Fixed as CreateNewTicket.
MethodHTTP method. POST in this scenario.
ResponseTypeExpected response format, in JSON (application/json).
RequestEncodingHow the request is encoded. Empty in this scenario.
URLFormatRequest URL of the API endpoint.

The <Parameter> nested inside <Request> defines the request body, with Name fixed as Data, Type fixed as Body, and Value holding the body content built from predefined variables.

Only the required variables are listed. For more, see Retrieve additional variables for global use.

VariableDescription
Variables from the AuthMethod scenarioVariables captured from the authentication credential inputs.
Target variables from follow-up requestsValues extracted from follow-up request responses.
{{.Subject}}Ticket subject, taken from the Subject parameter.
{{.Description}}Ticket description, taken from the Description parameter.
{{.LinkedId}}Unique ID of the call.
{{.Time}}Time the call was made or received (in the system’s time format).
{{.StartTimeUnix}}Unix timestamp of the call start time.
{{.EndTimeUnix}}Unix timestamp of the call end time.
{{.Call_From}}Name and number of the calling party. Format: Caller's name <Caller's number>.
{{.CallerName}}Caller’s name.
{{.CallerNumber}}Caller’s number.
{{.CalleeName}}Callee’s name.
{{.CalleeNumber}}Callee’s number.
{{.CrmId}}Unique ID of the CRM/Helpdesk user associated with a Cloud Voice extension.
{{.ExtensionFirstName}}Extension user’s first name.
{{.ExtensionLastName}}Extension user’s last name.
{{.ExtensionEmail}}Extension user’s email.
{{.ContactSyncType}}Contact type.
{{.ContactNumber}}Contact’s number.
{{.ContactId}}Unique ID of a contact.
{{.TicketId}}Unique ID of the ticket created from a call. To obtain it, add extra settings (see Retrieve the ticket ID for further operations).
{{.CallDuration}}Time between the call starting and ending.
{{.Talk_Duration}}Time between the call being answered and ending, in hh:mm:ss.
{{.Talk_Duration_Sec}}Time between the call being answered and ending, in seconds.
{{.Communication_Type}}Call direction: Inbound or Outbound.
{{.Call_Status}}Processing status: Missed (not answered) or Completed (connected and finished).
{{.Call_Log_Status}}Call status: Missed Call, Outgoing Call, Incoming Call, or Voicemail.
{{.CallDisposition}}Call disposition: MISSED, VOICEMAIL, BUSY, ANSWERED, or NO ANSWER.

This scenario logs the call activity of associated users to the CRM/Helpdesk.

<Scenario Id="CallJournal" Type="REST">
<Presets></Presets>
<Parameters>
<Parameter Name="EnableSubject" Value="1"></Parameter>
<Parameter Name="Subject" Value="Extension Call"></Parameter>
<Parameter Name="EnableDescription" Value="1"></Parameter>
<Parameter Name="Description" Value="Call: {{.Time}} {{.Call_Log_Status}} from {{.Call_From}} to {{.Call_To}} {{.Talk_Duration}}"></Parameter>
<Parameter Name="EnablePlayCallRecording" Value="1"></Parameter>
<Parameter Name="PlayCallRecording" Value="0"></Parameter>
<Parameter Name="EnableForwardCallLogForAnsweredAgent" Value="0"></Parameter>
<Parameter Name="ForwardCallLogForAnsweredAgent" Value="0"></Parameter>
</Parameters>
<Requests>
<Request Name="CallJournal" Method="POST" Weight="0" ResponseType="application/json" RequestEncoding="" URLFormat="https://www.api.example.com/v2/Calls" RefreshTime="" IsDelete="0">
<Parameters>
<Parameter Name="Data" Type="Body" Value="{&#xA; &#34;data&#34;: [&#xA; {&#xA; &#34;{{.Owner}}{{.WhoModule}}&#34;: {&#xA; &#34;Description&#34;: &#34;{{.Description}}&#34;,&#xA; &#34;Voice_Recording__s&#34;: &#34;{{.RecordPath}}&#34;,&#xA; &#34;Call_Start_Time&#34;: &#34;{{TimeFormat .StartTimeUnix &#39;yyyy-MM-ddTHH:mm:ss-z&#39; &#39;1&#39;}}&#34;,&#xA; &#34;Subject&#34;: &#34;{{.Subject}}&#34;,&#xA; &#34;Call_Type&#34;: &#34;Inbound&#34;,&#xA; &#34;Call_Result&#34;: &#34;{{.Call_Log_Status}}&#34;,&#xA; &#34;Call_Duration&#34;: &#34;{{.Talk_Duration_Sec}}&#34;&#xA; }&#xA; }&#xA; ]&#xA;}"></Parameter>
</Parameters>
<Outputs></Outputs>
</Request>
<Request Name="CallJournalUpdate" Method="PUT" Weight="0" ResponseType="application/json" RequestEncoding="" URLFormat="https://www.api.example.com/v2/Calls/{{.CallId}}" RefreshTime="" IsDelete="0">
<Parameters>
<Parameter Name="Data" Type="Body" Value="{&#xA; &#34;data&#34;: [&#xA; {&#xA; &#34;{{.Owner}}{{.WhoModule}}&#34;: {&#xA; &#34;Description&#34;: &#34;{{.Description}}&#34;,&#xA; &#34;Voice_Recording__s&#34;: &#34;{{.RecordPath}}&#34;,&#xA; &#34;Call_Start_Time&#34;: &#34;{{TimeFormat .StartTimeUnix &#39;yyyy-MM-ddTHH:mm:ss-z&#39; &#39;1&#39;}}&#34;,&#xA; &#34;Subject&#34;: &#34;{{.Subject}}&#34;,&#xA; &#34;Call_Type&#34;: &#34;Inbound&#34;,&#xA; &#34;Call_Result&#34;: &#34;{{.Call_Log_Status}}&#34;,&#xA; &#34;Call_Duration&#34;: &#34;{{.Talk_Duration_Sec}}&#34;,&#xA; &#34;AI_Transcription&#34;: &#34;{{.AI_Transcription}}&#34;,&#xA; &#34;AI_Summary&#34;: &#34;{{.AI_Summary}}&#34;,&#xA; &#34;Call_Note&#34;: &#34;{{.Call_Note}}&#34;&#xA; }&#xA; }&#xA; ]&#xA;}"></Parameter>
</Parameters>
<Outputs></Outputs>
</Request>
</Requests>
</Scenario>
AttributeDescription
IdScenario identifier. Fixed as CallJournal.
TypeScenario type. REST, the scenario runs a REST API through an HTTP request.

Configuration settings for the scenario, as Name/Value pairs:

SettingDescription
EnableSubjectWhether the call log subject is configurable in the integration: 0 disable, 1 enable.
SubjectDefault subject value. Default: Extension Call. You can also use supported variables (see the variable list).
EnableDescriptionWhether the call log description is configurable: 0 disable, 1 enable.
DescriptionDefault description value. Default: {{.Time}} {{.Communication_Type}} {{.Call_Status}} - from {{.Call_From}} to {{.Call_To}} {{.Talk_Duration}}. See the variable list.
EnablePlayCallRecordingWhether playing call recordings within the CRM/Helpdesk is configurable: 0 disable, 1 enable.
PlayCallRecordingDefault state of the recording-playback option: 0 disable, 1 enable.
EnableForwardCallLogForAnsweredAgentWhether the option to suppress missed-call logs for non-answering agents (on queue or ring group calls) is configurable in the integration.
ForwardCallLogForAnsweredAgentDefault state of that option. 0 disable. 1 enable, for queue and ring group calls, the log syncs only to the CRM/Helpdesk of the agent who answered, and missed-call logs for the same call are not synced to agents who did not answer.
AttributeDescription
NameRequest name. CallJournal creates a new call log in the CRM/Helpdesk. CallJournalUpdate updates an existing call log with additional information.
MethodHTTP method: POST or PUT.
ResponseTypeExpected response format, in JSON (application/json).
RequestEncodingHow the request is encoded. Empty in this scenario.
URLFormatRequest URL of the API endpoint.

The <Parameter> nested inside <Request> defines the request body, with Name fixed as Data, Type fixed as Body, and Value holding the body content built from predefined variables.

The request body accepts every call variable listed for Automatic ticket creation, plus the following recording and AI fields:

VariableDescription
{{.EnableCallRecording}}Whether call recording is enabled: 0 disabled, 1 enabled.
{{.AI_Transcription}}AI-generated call transcript.
{{.AI_Summary}}AI-generated call summary.
{{.Call_Note}}Call note content.

Only the required variables are documented here. For more, see Retrieve additional variables for global use.

This scenario syncs the chat messages exchanged between associated users and contacts to the CRM/Helpdesk.

<Scenario Id="ChatJournal" Type="REST">
<Presets></Presets>
<Parameters>
<Parameter Name="EnableSubject" Value="1"/>
<Parameter Name="Subject" Value="PhoneSystem External Chat Session"/>
<Parameter Name="EnableCreateType" Value="0"/>
<Parameter Name="CreateType" Value=""/>
</Parameters>
<Requests>
<Request Name="ChatJournalDefault" Method="POST" Weight="0" ResponseType="application/json" RequestEncoding="" URLFormat="https://www.api.example.com/crm/v7/Tasks" RefreshTime="" IsDelete="0">
<Parameters>
<Parameter Name="Data" Type="Body" Value="{ &quot;data&quot;: [ { &quot;Owner&quot;: { &quot;id&quot;: &quot;{{.OwnerId}}&quot; }, &quot;Who_Id&quot;: &quot;{{.ContactEntityId}}&quot;, &quot;Subject&quot;: &quot;{{.Subject}}&quot;, &quot;Due_Date&quot;: &quot;{{ TimeFormat .StartTimeUnix &quot;yyyy-MM-dd&quot; &quot;0&quot; }}&quot;, &quot;Closed_Time&quot;: &quot;{{ TimeFormat .EndTimeUnix &quot;yyyy-MM-ddTHH:mm:ss.000Zz&quot; &quot;0&quot; }}&quot;, &quot;Status&quot;: &quot;Completed&quot;, &quot;Priority&quot;: &quot;Normal&quot;, &quot;Description&quot;: &quot;Message Channel Type: {{.Channel_Display}}\n\n{{.Messages}}&quot; } ] }"/>
</Parameters>
<Outputs/>
</Request>
</Requests>
</Scenario>
AttributeDescription
IdScenario identifier. Fixed as ChatJournal.
TypeScenario type. REST, the scenario runs a REST API through an HTTP request.

Configuration settings for the scenario, as Name/Value pairs:

SettingDescription
EnableSubjectWhether the subject of the synced record is configurable: 0 disable, 1 enable.
SubjectDefault subject value. Default: PhoneSystem External Chat Session. You can also use supported variables (see the variable list).
EnableCreateTypeReserved field (not applicable).
CreateTypeReserved field (not applicable).
AttributeDescription
NameRequest name. Fixed as ChatJournalDefault.
MethodHTTP method: POST or PUT.
ResponseTypeExpected response format, in JSON (application/json).
RequestEncodingHow the request is encoded. Empty in this scenario.
URLFormatRequest URL of the API endpoint.

The <Parameter> nested inside <Request> defines the request body, with Name fixed as Data, Type fixed as Body, and Value holding the body content built from predefined variables.

Only the required variables are listed. For more, see Retrieve additional variables for global use.

VariableDescription
Variables from the AuthMethod scenarioVariables captured from the authentication credential inputs.
Target variables from follow-up requestsValues extracted from follow-up request responses.
{{.ContactNumber}}Phone number of the CRM/Helpdesk contact.
{{.ContactEmail}}Email address of the CRM/Helpdesk contact.
{{.ContactName}}Name of the CRM/Helpdesk contact.
{{.ContactEntityId}}Entity ID of the matched contact, lead, or account.
{{.ContactEntityType}}Type of the matched entity (contact, lead, or account).
{{.QueueName}}Name of the message queue, included when the chat is routed to a queue.
{{.Messages}}The messages sent and received during the session, including time, senders, and content.
{{.ExtensionNumber}}Extension number of the extension or agent who handled the messages or closed the session. If the system closes the session automatically, this is PBX System.
{{.ExtensionFirstName}}First name of the extension or agent who handled the messages or closed the session. If the system closes it automatically, this is PBX System.
{{.ExtensionLastName}}Last name of the extension or agent who handled the messages or closed the session. If the system closes it automatically, this is PBX System.
{{.ExtensionEmail}}Email address of the extension or agent who handled the messages.
{{.ChatDuration}}Chat session duration, in hh:mm:ss. To convert to total minutes, use {{ToMinutes .ChatDuration}}.
{{.StartTimeUnix}}Unix timestamp (seconds) of the session start. Format it as a local time string with {{ TimeFormat .StartTimeUnix "yyyy-MM-ddTHH:mm:ss.000Zz" "0" }}, as UTC with "1" instead of "0", or convert to milliseconds with {{ToMillis .StartTimeUnix}}.
{{.EndTimeUnix}}Unix timestamp (seconds) of the session end. Format it as a local time string with {{ TimeFormat .EndTimeUnix "yyyy-MM-ddTHH:mm:ss.000Zz" "0" }}, as UTC with "1" instead of "0", or convert to milliseconds with {{TsSecToMilliSec .EndTimeUnix}}.

Beyond the scenarios you set on the configuration page, you can add custom configurations by editing the template directly.

To add custom request headers, add one or more parameters with Type set to Header. In the example below, an X-Auth-Token header carries the API key. Father (fixed as PopulateTemplateString) groups the related parameters, Type (fixed as Header) marks the parameter as an HTTP header, and Name and Value set the header. The request then includes X-Auth-Token:{{.api_key}}.

<Requests>
<Request Name="contacts" Method="GET" ResponseType="application/json" URLFormat="https://api.example.com/contacts/search?number={{.Phone}}">
<Parameters>
<Parameter Father="PopulateTemplateString" Name="X-Auth-Token" Type="Header" Value="{{.api_key}}" />
</Parameters>
<Outputs>
...
</Outputs>
</Request>
</Requests>

In the AuthMethod scenario, add a TokenInvalid parameter to help distinguish a token problem from other errors. Set its Value to the token-related error code or specific content. If the HTTP status is not 200 and the response body contains that content, the error is recognized as TokenInvalid.

<Scenario Id="AuthMethod" Type="AUTH">
<Presets />
<Parameters>
<Parameter Name="AuthMethod" Value="oauth2" />
...
<Parameter Father="TokenErrorMap" Type="TokenInvalid" Name="TokenInvalid" Value="INVALID_TOKEN" />
...
</Parameters>
<Requests />
<Responses />
</Scenario>

Retrieve additional variables for global use

Section titled “Retrieve additional variables for global use”

If you need variables beyond the built-in ones, for example common information you want to reuse globally, define a GetGlobalInfo scenario with the requests that retrieve those values.

When the integration completes or Cloud Voice starts, the requests inside GetGlobalInfo are sent to the CRM/Helpdesk and the values are stored in the Output elements. Each output’s name maps directly to a variable name, making it available in other scenarios (except the authentication scenario). In the example below, GetGlobalInfo retrieves DepartmentId and PortalName.

<Scenario Id="GetGlobalInfo" Type="REST">
<Presets />
<Parameters />
<Requests>
<Request Name="GetDepartments" Method="GET" ResponseType="application/json" URLFormat="https://desk.example.{{.domain_suffix}}/api/v1/departments">
<Parameters />
<Outputs>
<Output Name="DepartmentId" Path="data.#.id" />
</Outputs>
</Request>
<Request Name="GetOrganizations" Method="GET" ResponseType="application/json" URLFormat="https://desk.example.{{.domain_suffix}}/api/v1/organizations">
<Parameters />
<Outputs>
<Output Name="PortalName" Path="data.#(portalName!=&quot;&quot;).portalName" />
</Outputs>
</Request>
</Requests>
</Scenario>

If the first contact query does not return everything you need, run a further query using the returned contact ID or other fields. In the example below, the initial contact-sync query does not return the phone numbers:

<Scenario Id="SyncContactAuto" Type="REST">
<Presets />
<Parameters>
<Parameter Name="ContactUrlType" Value="specify_url_format" />
...
</Parameters>
<Requests>
<Request Name="contacts" Method="GET" ResponseType="application/json" URLFormat="https://{{.subdomain}}.example.com/api/v2/users?query=phone:{{UrlEncode .Phone}}&amp;role[]=end-user">
<Parameters />
<Outputs Next="GetIdentities">
<Output Name="ContactsId" Path="users.#.id" />
<Output Name="FirstName" Path="users.#.name" />
<Output Name="BusinessNumber" Path="users.#.phone" />
...
<!-- The following phone number fields return empty. -->
<Output Name="BusinessNumber2" Path=""></Output>
<Output Name="BusinessFaxNumber" Path=""></Output>
<Output Name="MobileNumber" Path=""></Output>
<Output Name="MobileNumber2" Path=""></Output>
<Output Name="HomeNumber" Path=""></Output>
<Output Name="HomeNumber2" Path=""></Output>
...
</Outputs>
</Request>
</Requests>
</Scenario>

To retrieve the missing numbers, chain scenarios:

  1. Add a Next attribute to the original scenario. In the contact-sync scenario, add a Next attribute to the <Outputs> element of the initial query request. Its value is the name of the request you will define in the Common scenario, here, GetIdentities.

    <Outputs Next="GetIdentities">
  2. Create a Common scenario. Create a scenario named Common with type REST (both are fixed), then add a request named GetIdentities that queries the extra contact information using {{.ContactsId}} from the initial request.

    <Scenario Id="Common" Type="REST">
    <Presets></Presets>
    <Parameters></Parameters>
    <Requests>
    <Request Name="GetIdentities" Method="GET" URLFormat="https://{{.subdomain}}.example.com/api/v2/users/{{.ContactsId}}/identities" ResponseType="application/json">
    <Parameters></Parameters>
    <Outputs>
    <Output Name="BusinessNumber2" Path="identities.#(type==&quot;phone_number&quot;)#|1.value"></Output>
    <Output Name="BusinessFaxNumber" Path="identities.#(type==&quot;phone_number&quot;)#|2.value"></Output>
    <Output Name="MobileNumber" Path="identities.#(type==&quot;phone_number&quot;)#|3.value"></Output>
    <Output Name="MobileNumber2" Path="identities.#(type==&quot;phone_number&quot;)#|4.value"></Output>
    <Output Name="HomeNumber" Path="identities.#(type==&quot;phone_number&quot;)#|5.value"></Output>
    <Output Name="HomeNumber2" Path="identities.#(type==&quot;phone_number&quot;)#|6.value"></Output>
    <Output Name="HomeFaxNumber" Path="identities.#(type==&quot;phone_number&quot;)#|7.value"></Output>
    <Output Name="OtherNumber" Path="identities.#(type==&quot;phone_number&quot;)#|8.value"></Output>
    </Outputs>
    </Request>
    </Requests>
    </Scenario>

    Because the request is referenced through the Next attribute of the original scenario, the variable from the initial query is passed to it. The request runs and backfills its Outputs into the initial response to complete the record.

Retrieve the ticket ID for further operations

Section titled “Retrieve the ticket ID for further operations”

In a Helpdesk template, you can retrieve the ticket ID for later operations, such as updating the ticket or referencing it in the call journal. For example, when a ticket is created before the call (when the phone rings), it may be missing information you can fill in later using its TicketId.

<Scenario Id="CreateNewTicket" Type="REST">
<Presets />
<Parameters>
<Parameter Name="EnableSubject" Value="1" />
...
<Parameter Name="NeedSyncContact" Value="1" />
</Parameters>
<Requests>
<Request Name="CreateNewTicket" Method="POST" ResponseType="application/json" URLFormat="https://{{.domain}}/api/v1/tickets">
<Parameters>
<Parameter Name="Data" Type="Body" Value="{&quot;departmentId&quot;:&quot;{{.DepartmentId}}&quot;,&quot;subject&quot;:&quot;{{.Subject}}&quot;,&quot;contactId&quot;:&quot;{{.ContactId}}&quot;,&quot;phone&quot;:&quot;{{.ContactNumber}}&quot;,&quot;description&quot;:&quot;{{.Description}}&quot;}" />
</Parameters>
<Outputs>
<Output Name="TicketId" Path="id" />
</Outputs>
</Request>
<Request Name="UpdateTicket" Method="POST" ResponseType="application/json" URLFormat="https://{{.domain}}/api/v1/tickets/{{.TicketId}}/comments">
<Parameters>
<Parameter Name="Data" Type="Body" Value="{&quot;isPublic&quot;:&quot;true&quot;,&quot;content&quot;:&quot;{{.Description}}&quot;}" />
</Parameters>
<Outputs />
</Request>
</Requests>
</Scenario>
  1. Retrieve the ticket ID. In the CreateNewTicket scenario, add an <Output> element to extract the ID from the CreateNewTicket request’s response. This stores the TicketId for later use.

    <Outputs>
    <Output Name="TicketId" Path="id" />
    </Outputs>
  2. Update the ticket. Add a request that updates the ticket in the corresponding call record using the retrieved ID. The ticket is then completed with all necessary data after its initial creation.

    <Request Name="UpdateTicket" Method="POST" ResponseType="application/json" URLFormat="https://{{.domain}}/api/v1/tickets/{{.TicketId}}/comments">
    <Parameters>
    <Parameter Name="Data" Type="Body" Value="{&quot;isPublic&quot;:&quot;true&quot;,&quot;content&quot;:&quot;{{.Description}}&quot;}" />
    </Parameters>
    <Outputs />
    </Request>