API Designer
API Designer provides a workbench for developers to develop HTTP based APIs which can be exposed to the VTAP runtime or the external application for integration easily.
APIs can be defined using VADL specification. APIs access needs user authorization and follows standard record access configuration made within CRM.
-
API Designer
- VADL Specification
- API Endpoint
-
API Samples
- Select Records
- Select Records With Value Binding {#select-records-with-value-binding}
- Create Record
- Create Record With Reference Field
- Create Record and related to a parent records
- Update Record
- Upsert
- Update a record and add a mention
- Invoke HTTP Rest API with bearer token
- Invoke HTTP Rest API with basic auth tokens
- REST URL Builder
- OAuth Support
- Setting Headers
- SOAP Support
- Special Value Binding
VADL Specification
Vtiger Application Definition Language (VADL) is based on XML syntax to enable administrators or developers to be able to define API without needing deep programming skills.
<?xml version="1.0" ?>
<api method="post">
<!-- definition goes here -->
</api>
VADL allows you to
- Define APIs
- CURD (Create, Retrieve, Update, Delete) on entity modules.
- Invoke HTTP based (REST / SOAP) endpoint through (GET/POST/PUT/DELETE) methods
- With Authentication (Basic / Bearer token based)
- Accept request parameters and bind as API inputs.
- Bind API inputs to VTAP runtime configuration store.
VADL API definitions
Name | Description | Example |
---|---|---|
api | entire api definition is encapsulated inside api node, method attribute set the type(get,post,put,delete) of http request. | <api method='post'></api> |
select | this will let you select the vtiger record data, you can select which fields to be fetched, filter records and sort them | <api method='get'><select module='Contacts'></select></api> |
create | this will let you create vtiger record | <api method='post'><create module='Contacts'></create></api> |
update | this will let you update vtiger record | <api method='put'><update module='Contacts'></update></api> |
delete | this will help you delete vtiger record | <api method='delete'><delete module='Contacts'></delete></api> |
rest | this will help you connect with other application | <api method='get'><rest method="get"><url>https://slack.com/api/conversations.list</url></rest></api> |
soap | connect with legacy soap api's | <api method='get'><soap method="get"><auth><basic username="" password=""></basic></auth><url></url></soap></api> |
API Endpoint
API defined through API Designer can be access through the restapi endpoint as follows:
https://vtigercrm.instance.url/restapi/vtap/api/APINAME
HTTP Basic Authentication (username and accesskey) should be used and HTTP Method is controlled within API definition.
API Samples
Select Records
To select (firstname, lastname) record fields of Module for matching email (=[email protected]) the API definition would be:
<?xml version="1.0" ?>
<api method="get">
<select module="Contacts">
<record>
<field name="firstname"> </field>
<field name="lastname"> </field>
</record>
<where>
<field name="email" condition="eq" value="[email protected]"></field>
</where>
<sort>
<field name="annualrevenue" order="desc"></field>
</sort>
<limit max="10"></limit>
</select>
</api>
Conditions
Condition in where clause supports below options
Condition | Description |
---|---|
eq | Equals (=), defaults if not passed |
neq | Not Equals (!=) |
gt | Greater Than (>) |
lt | Less Than (<) |
gte | Greater Than OR Equal To (>=) |
lte | Less Than OR Equal To (>=) |
in | Select in Multiple VALUES (IN) |
like | Like (%VALUE%) |
Select Records With Value Binding {#select-records-with-value-binding}
To select (firstname, lastname) of Contacts record where email field value matching incoming request parameter email_address
<?xml version="1.0" ?>
<api method="get">
<select module="Contacts">
<record>
<field name="firstname"> </field>
<field name="lastname"> </field>
</record>
<where>
<field name="contact_id" module="Contacts">
<select>
<where>
<field name="email" condition="eq" value="@emailaddress"></field>
</where>
</select>
</field>
</where>
</select>
</api>
Create Record
If the intent is to create Contacts module record by accepting (firstname, lastname, email) from the request parameter and respond back with record id then API definition for the same would be as shown below.
<?xml version="1.0" ?>
<api method="post">
<create module="Contacts">
<record>
<field name="firstname" value="@firstname"></field>
<field name="lastname" value="@lastname"></field>
<field name="email" value="@email"></field>
</record>
<return>
<field name="id"></field>
</return>
</create>
</api>
Create Record With Reference Field
Reference field rules can have a combination of select and create rules which gives the ability to create reference records if select does not yield any match.
<?xml version="1.0" ?>
<api method="post">
<create module="Potentials">
<record>
<field name="potentialname" value="@name"></field>
<field name="amount" value="@amount"></field>
<field name="contact_id" module="Contacts">
<select>
<where>
<field name="email" value="@email"></field>
</where>
</select>
<create>
<record>
<field name="lastname" value="@lastname"></field>
<field name="firstname" value="@firstname"></field>
<field name="email" value="@email"></field>
<field name="contacttype" value="Lead"></field>
</record>
</create>
</field>
</record>
</create>
</api>
Create Record and related to a parent records
You can create a record and also link it parent record using link node. In the below example you will see label in link node, this is the relationship name(label you see in related list in summary page) between newly created and parent record. If you are not sure then you can leave it skip mentioning it.
<?xml version="1.0"?>
<api method="post">
<create module="Documents">
<record>
<field name="notes_title" value="@notes_title"></field>
<field name="notecontent" value="@notecontent" presence="optional"></field>
<field name="filelocationtype" value="I"></field>
<field name="fileversion" value="@fileversion" presence="optional"></field>
<field name="filestatus" value="1"></field>
<field name="folderid" value="22x1"></field>
<field name="document_source" value="Vtiger"></field>
<field name="document_type" value="Public"></field>
</record>
<link label="Documents">
<select module="Contacts">
<where>
<field name="id" value="@parent_id"></field>
</where>
</select>
</link>
<return>
<field name="id"></field>
</return>
</create>
</api>
Update Record
To replace email field value with incoming parameter (new_email) on all Contacts record matching incoming parameter (old_email) and respond back with record ID of changed records.
<?xml version="1.0" ?>
<api method="put">
<update module="Contacts">
<record>
<field name="email" value="@new_email"></field>
</record>
<where>
<field name="email" condition="eq" value="@old_email"></field>
</where>
<return>
<field name="id"></field>
</return>
</update>
</api>
Upsert
You can update and create in one single api
<?xml version="1.0" ?>
<api method="post" module="Contacts">
<upsert>
<where>
<field name="id" condition="eq" value="@CRMID"></field>
</where>
<sort>
<field name="id" order="desc"></field>
</sort>
<limit max="1"></limit>
<update>
<record>
<field name="email" value="@email" presence="optional"></field>
<field name="cardnumber" value="@card" presence="optional"></field>
</record>
</update>
<create>
<record>
<field name="firstname" value="@firstname" presence="optional"></field>
<field name="lastname" value="@lastname" presence="optional"></field>
<field name="email" value="@email" presence="optional"></field>
<field name="account_id" module="Accounts" presence="optional">
<select>
<where>
<field name="website" value="@website"></field>
</where>
<sort>
<field name="domain" order="descending"></field>
</sort>
</select>
</field>
</record>
</create>
<return>
<field name="id"></field>
<field name="lastname"></field>
<field name="account_id"></field>
</return>
</upsert>
</api>
Update a record and add a mention
<?xml version="1.0" ?>
<api method="POST">
<update>
<record>
<field name="leadsource" value="Facebook" presence="optional"></field>
</record>
<where>
<field name="status" value="Active"></field>
</where>
<return>
<field name="id"></field>
</return>
<mention>
<template>
<![CDATA[
<br>
<table>
<tr>
<td>Marketing Channel: %s</td></tr>
<tr>
<td>New lead created from Facebook: %s</td>
</tr>
</table>
]]>
</template>
<values>
<value name="fld_marketingchannel"></value>
<value name="email"></value>
</values>
<text>
//either use template or text, one of them.
</text>
</mention>
<return>
<value name="assigned_user_id"></value>
<value name="fld_marketingchannel"></value>
<value name="email"></value>
</return>
</update>
</api>
Note:
- Using template will automatically mention the owner of the record. If you are using text then you need to mention the user in the content for example "hey @administrator, check this record".
- You can mention either inside text or template. If both mentioned then only "text" will take precedence.
- If assigned_user_id(owner) is part of return then it will mention that user, else the mention will not notify anyone, and comment will not be added. This will be the case if you are using template.
- If you just want to add a comment without mentioning anyone then use text node.
Invoke HTTP Rest API with bearer token
Using bearer token invoke Google Sheet API
<?xml version="1.0" ?>
<api method="get">
<rest>
<url sheetID="@sheetid">https://sheets.googleapis.com/v4/spreadsheets/$sheetID</url>
<auth>
<bearer token="@token" />
</auth>
</rest>
</api>
Invoke HTTP Rest API with basic auth tokens
Use basic authentication to invoke custom app's api. Below is one example for connecting atlassian api. You can directly give email and api key in username and password or if you want to take these details from user and store in vtiger then access them using VTAP data api's.
<?xml version="1.0" ?>
<api method="get">
<rest>
<url>https://your-domain.atlassian.net/rest/api/2/issue/createmeta</url>
<auth>
<basic username="$apps.$app.Contacts.atlassian_email" password="$apps.$app.Contacts.atlassian_apikey"></auth>
</auth>
</rest>
</api>
REST URL Builder
Rest API URL can be composed with dynamic value binding by passing arguments in the url node.
To construct URL of the form
Where ${sheet_id} needs dynamic binding from the request parameter followed by the static part.
You can achieve by following url rules.
<url
SHEETID="@sheetid" OPTIONS="values/Sheet1!A1:append?valueInputOption=RAW">
https://sheets.googleapis.com/v4/spreadsheets/$SHEETID/$OPTIONS</url>
OAuth Support
VTAP server end handles the OAuth2 flow and lets you focus on getting the user authentication for access data of the desired application.
To make API requests with such OAuth2 credentials you need to cite (type, service and module) on the oauth rule definition.
type | vtap | |
service | Target service to connect via OAuth2 | Google, Facebook etc.. |
module | CRM Module which owns the OAuth2 grant |
Example:
<?xml version="1.0" ?>
<api method="post">
<rest method="post">
<url SHEETID="@sheetid" OPTIONS="values/Sheet1!A1:append?valueInputOption=RAW">https://sheets.googleapis.com/v4/spreadsheets/$SHEETID/$OPTIONS</url>
<auth>
<oauth type="vtap" service="Google" module="CUSTOM_MODULE"> </oauth>
</auth>
<parameters raw-post-data="true">
<parameter name='values' value='@row_data' presence="optional"></parameter>
</parameters>
</rest>
</api>
Setting Headers
To set headers to the request add headers node inside rest node.
Example:
<?xml version="1.0" ?>
<api method="post">
<rest method="post">
<url>https://sheets.googleapis.com/v4/spreadsheets</url>
<headers>
<header name="Content-Type" value="application/json"> </header>
</headers>
</rest>
</api>
SOAP Support
<api method="get">
<soap>
<url>https://some_soap_endpoint?wsdl</url>
<auth>
<basic username="" password=""></basic>
</auth>
<operation name="SendSMS">
<parameters>
<parameter name="Phone" value="123-456-789-1"></parameter>
<parameter name="Content" value="SMS by Vtiger"></parameter>
</parameters>
</operation>
</soap>
</api>
Special Value Binding
$login.{$user_field_name} | Logged in user object field value
$user_field_name can be:
|
$vtapoauth.{$SERVICE}{$EXT_MODULE_NAME} | To bind bearer token VTAP has been acquired for the SERVICE and MODULE_NAME already.
Example: $vtapoauth.Google.vtcmsheetview |
$apps.$user.{$key} | data stored in vtap user data store |
$apps.$app.{$key} | data stored in vtap app store |
$apps.$prefs.{$key} | data stored in vtap preferences store |