Zoho CRM Connector
Documentation
Version: 8
Documentation

Zoho CRM Connector - Source Code


<?xml version="1.0" encoding="utf-8"?>
<ApiConfig Name="Zoho CRM"
  EngineVersion="16"
  Version="8"
  Id="1C3FF995-9EE6-4C55-A654-37141622704B"
	Slug="zoho-crm-connector"
	Desc="Zoho CRM Connector can be used to integrate Zoho CRM API in your App / BI Tools. You can exchange data on Accounts, Leads, Contacts and many other modules."
	HelpLink="https://www.zoho.com/crm/developer/docs/api/"
	Logo="data:image/png;base64,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"
	>
  <VersionHistory>
	<Change Date="2024-06-02">Allow to choose API version</Change>
	<Change Date="2024-06-02">Allow select API version using connection level Option (Service URL must be changed to match API Version Parameter). Default Version is V2 and its almost 2 times faster than higher API version (e.g. V3+) but V2 may return less number of columns compared to new API versions (e.g. v3...v7+). API V2 makes less number of requests and returns more records per call (200 rows), on the other side V3+ has limits of max 50 fields in each Get Records API calls. To avoid this limitation in V3+ API we used /{module}?ids={150 ids} workaround but this is still slower compred to older API (v2) approach. Choose new API if you have a valid reason (e.g. you need additional new columns exposed in v3+) else stick with older version V2 (its default setting).</Change>
	<Change Date="2024-06-02">Updated sort order for select and lookup endpoints now they should match with field orders returned from get_module_fields</Change>
    <Change Date="2024-06-02">Updated cache mode for get_module_fields to UseRawCache</Change>
    <Change Date="2024-06-02">Updated datacenter list (Added CA, SA, JP and more)</Change>    
    <Change Date="2024-06-02" Type="Fix">Lookup fields are NULL and Lookup_Field_Id is not in the output (e.g. select Account_Name from Deals)</Change>
    <Change Date="2024-06-02">Document Lookup write examples (Insert, Update)</Change>    
    <Change Date="2023-04-25">Show non-approved records too when you query by id (e.g. SELECT * FROM Leads WHERE Id=1234)</Change>
    <Change Date="2023-04-25">Added Id column support for DELETE (e.g. DELETE FROM Account Where Id=123)</Change>
    <Change Date="2023-04-25">Added api_name column in the output for UPSERT so when error occurs you know which field causing it</Change>
    <Change Date="2022-04-27">Added retry logic for limit reached error (status code 429)</Change>
    <Change Date="2022-01-31">Added new endpoints for Tags read/write (get_tags, get_tag_record_count, post_tags)</Change>
    <Change Date="2022-01-31">Added support for Lookup operation in SELECT, and WHERE clause for DELETE and UPDATE</Change>
    <Change Date="2021-11-02">Fixed bulk delete operation issue</Change>
    <Change Date="2021-03-15">Renamed If-Modified-Since option to ModifiedSince</Change>
    <Change Date="2021-01-15" Type="Fix">If-Modified-Since option is not working - Read data modified after some datetime</Change>
    <Change Date="2020-12-01">Initial version</Change>
  </VersionHistory>

  <ServiceUrls>
    <ServiceUrl Name="United States (US) Datacenter" Url="https://www.zohoapis.com/crm/[$Version$]"/>
    <ServiceUrl Name="Europe (EU) Datacenter" Url="https://www.zohoapis.eu/crm/[$Version$]"/>
    <ServiceUrl Name="Australia (AU) Datacenter" Url="https://www.zohoapis.com.au/crm/[$Version$]"/>
    <ServiceUrl Name="India (IN) Domain" Url="https://www.zohoapis.in/crm/[$Version$]"/>
	<ServiceUrl Name="Japan (JP) Datacenter" Url="https://www.zohoapis.jp/crm/[$Version$]"/>
    <ServiceUrl Name="China (CN) Datacenter" Url="https://www.zohoapis.com.cn/crm/[$Version$]"/>
	<ServiceUrl Name="Canada (CA) Datacenter" Url="https://www.zohoapis.ca/crm/[$Version$]"/>
	<ServiceUrl Name="Saudi Arabia (SA) Datacenter" Url="https://www.zohoapis.sa/crm/[$Version$]"/>
  </ServiceUrls>
 

  <!-- https://www.zoho.com/crm/developer/docs/api/access-refresh.html -->
  <Auths>
    <Auth Type="OAuth" Desc="OAuth Connection for Zoho CRM API" HelpLink="https://www.zoho.com/crm/developer/docs/api/register-client.html"
          ConnStr="Provider=Custom;OAuthVersion=OAuth2;ScopeSeparator={space};ReturnUrl=[$RedirectUrl$];ExtraAttributesForAuthRequest=access_type=offline&amp;prompt=consent;AuthUrl=[$AccountUrl$]/oauth/v2/auth;TokenUrl=[$AccountUrl$]/oauth/v2/token;ClientId=[$ClientId$];ClientSecret=[$ClientSecret$];Scope=[$Permissions$];ExpiresInAttribute=expires_in_sec;" TestEndPoint="get_modules">
      <Params>
        <Param Name="ClientId" />
        <Param Name="ClientSecret" Secret="True" />
        <Param Name="Permissions" Value="ZohoCRM.settings.all ZohoCRM.modules.all ZohoCRM.coql.READ" Desc="To access Visists table you need add extra permissions and re-generate token (e.g. Append ZohoCRM.modules.visits.ALL OR try ZohoCRM.modules.visits.READ, ZohoCRM.modules.visits.DELETE to the value for this property)"/>
        <Param Name="AccountUrl" Value="https://accounts.zoho.com"
               Options="United States (US) Datacenter=https://accounts.zoho.com;
			   United Kingdom (UK) Datacenter=https://accounts.zoho.uk;
			   Europe (EU) Datacenter=https://accounts.zoho.eu;
			   Canada (CA) Datacenter=https://accounts.zohocloud.ca;
			   Australia (AU) Datacenter=https://accounts.zoho.au;
			   India (IN) Datacenter=https://accounts.zoho.in;
			   Japan (JP) Datacenter=https://accounts.zoho.jp;			   
			   Saudi Arabia (SA) Datacenter=https://accounts.zoho.sa;			   
			   China (CN) Datacenter=https://accounts.zoho.com.cn;"   

			   HelpLink="https://www.zoho.com/accounts/protocol/oauth/multi-dc.html"
			   />
        <Param Name="RedirectUrl" Value="https://zappysys.com/oauth" Desc="This is the redirect URL you entered when you created app in Zoho Portal. URL must match exactly including trailing slash" />
		<Param Name="Version" Label="API Version" Value="v2" Options="v2 (Fast)=v2;v3=v3;v4=v4;v5=v5;v6=v6;v7=v7;Enter Your Custom Version=type-version-here" Desc="Zoho CRM API version. After v2 there are some changes the way fields returned so choose API version carefully. V2 is faster compred to newer version." />
		
        <!--below not exposed as root level property in HTTP Connection so use as placeholder-->
        <Param Name="RetryMode" Value="RetryWhenStatusCodeMatch" Options="None;RetryAny;RetryWhenStatusCodeMatch;" Hidden="True"  HelpLink="https://www.zoho.com/crm/developer/docs/api/v2/status-codes.html" />
        <Param Name="RetryStatusCodeList" Value="429" Hidden="True" />
        <Param Name="RetryCountMax" Value="5" Hidden="True" />
        <Param Name="RetryMultiplyWaitTime" Value="True" Hidden="True" />
	
      </Params>
      <Notes>
        <![CDATA[To register custom App, perform the following steps (Detailed steps found in the help link at the end)
<ol>
  <li>Go to <a target="_blank" href="https://api-console.zoho.com/">Zoho API Console</a>
  <li>Click <b>Add Client</b> link
  <li>Select <b>Server-based Applications</b> option
  <li>Enter desired client name (Display purpose only)</b>
  <li>Enter some URL for Company homepage</b>
  <li>For Authorized Redirect URI enter https://zappysys.com/oauth (Or enter your own but we recommend using ZappySys one if possible). This URL must match on Zoho Connector UI.
  <li>Click <b>CREATE</b>.
  <li>Copy Client ID and Secret and paste on Zoho Connector UI.
</ol>
]]>
      </Notes>
    </Auth>
  </Auths>

  <Template>
    <!-- When name not specified in EndPoints node .. its considered as base for all other template -->
    <EndPoint Name="Pagination">
      <Params>
        <Param Name="Filter" Type="Property" Desc="Filter for JSON" Value="$.data[*]" />
        <Param Name="NextUrlEndIndicator" Type="Property" Value="false" />
        <Param Name="StopIndicatorAttributeOrExpr" Type="Property" Value="$.info.more_records" />
        <Param Name="PagingMode" Type="Property" Value="ByUrlParameter" />
        <Param Name="PagingByUrlAttributeName" Type="Property" Value="page" />
        <Param Name="PagingByUrlEndStrategy" Type="Property" Value="DetectBasedOnMultipleRules" />
		
        <Param Name="PagingEndRules" Type="Property" 
				Value="&lt;ArrayOfPagingEndRule&gt;&lt;PagingEndRule&gt;&lt;Mode&gt;DetectBasedOnResponseStatusCode&lt;/Mode&gt;&lt;StatusCode&gt;204&lt;/StatusCode&gt;&lt;/PagingEndRule&gt;&lt;PagingEndRule&gt;&lt;Mode&gt;DetectBasedOnResponseStatusCode&lt;/Mode&gt;&lt;StatusCode&gt;304&lt;/StatusCode&gt;&lt;/PagingEndRule&gt;&lt;PagingEndRule&gt;&lt;Mode&gt;DetectBasedOnResponseStatusCode&lt;/Mode&gt;&lt;Mode&gt;DetectBasedOnRecordCount&lt;/Mode&gt;&lt;/PagingEndRule&gt;&lt;/ArrayOfPagingEndRule&gt;" />

		<Param Name="PageSize" Key="per_page" Value="" Options=";200;100;50;10" Type="Query" Hidden="True"/>

	  </Params>
    </EndPoint>
    <EndPoint Name="ModulePagination" Template="Pagination">
      <Params>
        <Param Name="approved" Type="Query" Label="Return Approved Records" Desc="To get the list of approved records. Default value is true." Options=";true;false;both"  />
        <Param Name="converted" Type="Query" Label="Return Converted Records" Desc="To retrieve the list of converted records. Default value is false." Options=";true;false;both"  />

      </Params>

      <OutputColumns>
        <!--Column Name="id" Label="Id" DataType="DT_WSTR" Length="25" /-->
        <Column Name="-Dynamic-" Expand="True" DataEndPoint="get_module_fields" DataEndPointParameters="module=[$parent.api_name$];Filter=$.fields[?(@json_type!='jsonobject')];"
                ColumnInfoMap="Name=api_name;DataType=data_type;Length=length;Raw=json_type"
                RawInfoMap="jsonobject;jsonarray"
                DataTypeMap="DT_BOOL=boolean;DT_I8=bigint;DT_I4=integer;DT_WSTR=profileimage,ownerlookup,text,picklist,phone,website,lookup;DT_DBTIMESTAMP=datetime,date;DT_R8=currency,double;DT_NTEXT=textarea"
                Order="1"
				/>

        <Column Name="[$parent.api_name$].name" Label="[$parent.api_name$]" Expand="True" DataEndPoint="get_module_fields" DataEndPointParameters="module=[$parent.api_name$];Filter=$.fields[?(@json_type=='jsonobject')];"
                ColumnInfoMap="Name=api_name;DataType=data_type;Length=length;Raw=json_type"
                RawInfoMap="jsonobject;jsonarray"
                DataTypeMap="DT_BOOL=boolean;DT_I8=bigint;DT_I4=integer;DT_WSTR=profileimage,ownerlookup,text,picklist,phone,website,lookup;DT_DBTIMESTAMP=datetime,date;DT_R8=currency,double;DT_NTEXT=textarea"
                Order="501"/>
        <Column Name="[$parent.api_name$].id" Label="[$parent.api_name$]_Id" Expand="True" DataEndPoint="get_module_fields" DataEndPointParameters="module=[$parent.api_name$];Filter=$.fields[?(@json_type=='jsonobject')];"
                ColumnInfoMap="Name=api_name;DataType=data_type;Length=length;Raw=json_type"
                RawInfoMap="jsonobject;jsonarray"
                DataTypeMap="DT_BOOL=boolean;DT_I8=bigint;DT_I4=integer;DT_WSTR=profileimage,ownerlookup,text,picklist,phone,website,lookup;DT_DBTIMESTAMP=datetime,date;DT_R8=currency,double;DT_NTEXT=textarea"
                Order="502"/>


        <Column Name="Created_By.id" Label="Created_By_Id" DataType="DT_WSTR" Length="25" Order="1001"/>
        <Column Name="Created_By.email" Label="Created_By_Email" DataType="DT_WSTR" Length="255" Order="1002"/>
        <Column Name="Created_By.name" Label="Created_By_Name" DataType="DT_WSTR" Length="255" Order="1003"/>

        <Column Name="Modified_By.id" Label="Modified_By_Id" DataType="DT_WSTR" Length="25" Order="1004"/>
        <Column Name="Modified_By.email" Label="Modified_By_Email" DataType="DT_WSTR" Length="255" Order="1005"/>
        <Column Name="Modified_By.name" Label="Modified_By_Name" DataType="DT_WSTR" Length="255" Order="1006"/>

        <Column Name="Owner.id" Label="Owner_Id" DataType="DT_WSTR" Length="25" Order="1007"/>
        <Column Name="Owner.email" Label="Owner_Email" DataType="DT_WSTR" Length="255" Order="1008"/>
        <Column Name="Owner.name" Label="Owner_Name" DataType="DT_WSTR" Length="255" Order="1009"/>



        <Column Name="$approval_state" DataType="DT_WSTR" Length="20" Order="1010"/>
        <Column Name="$approved" DataType="DT_BOOL" Order="1011"/>
        <Column Name="$state" DataType="DT_WSTR" Length="50" Order="1012"/>
      </OutputColumns>
    </EndPoint>

    <EndPoint Name="CRUD" Template=".">
      <OutputColumns>
        <Column Name="details.id" Label="id" DataType="DT_WSTR" Length="255" Order="-5" />
        <Column Name="code" DataType="DT_WSTR" Length="255" Order="-4" />
        <Column Name="message" DataType="DT_WSTR" Length="1000" Order="-3" />
        <Column Name="status" DataType="DT_WSTR" Length="255" Order="-2" />
      </OutputColumns>
    </EndPoint>

    <EndPoint Name="NoPagination" Template=".">

    </EndPoint>

  </Template>

  <EndPoints>

    <EndPoint Method="POST" Name="get_module_data_coql" Template="NoPagination"
      Label="Read Data (Query Mode - Max 200 Rows Only)"
      Url="/coql" Body="{&quot;select_query&quot;: &quot;[$sql_query$]&quot;}" Filter="$.data[*]">
      <Params>
        <Param Editor="MultiLine" Name="sql_query" Desc="Your SQL query for CRM (i.e. COQL (CRM Object Query Language)). Limtation - You can fetch maximum 200 rows using COQL Query. To read all rows use Table mode. (refer to help link to learn more about COQL)"
               HelpLink="https://zappysys.com/links?url=https://www.zoho.com/crm/developer/docs/api/COQL-Overview.html"
Value="select Last_Name, First_Name, Full_Name from Contacts where Last_Name not like 'Boyle' limit 200" Functions="JSONENCODE;TRIM"/>

      </Params>
    </EndPoint>

    <EndPoint Name="get_modules" Label="List Modules" Url="/settings/modules" Template="NoPagination" Cached="True" CachedTtl="60" HelpLink="https://www.zoho.com/crm/developer/docs/api/modules-api.html">
      <Params>
        <Param Name="Filter" Type="Property" Desc="Filter for JSON" Value="$.modules[*]"
               Options="All Modules=$.modules[*];Modules With API Support=$.modules[?(@api_supported==true)];Modules Without API Support=$.modules[?(@api_supported==false)]" />
      </Params>
    </EndPoint>

    <EndPoint Name="get_territories" Label="List Territories" Url="/settings/territories" Filter="$.territories[*]" Template="NoPagination" Cached="True" CachedTtl="60" HelpLink="https://www.zoho.com/crm/developer/docs/api/v2/territories.html">
    </EndPoint>

    <EndPoint Name="get_module_settings" Label="List Module Settings" Url="/settings/modules/[$module$]" Cached="True" CachedTtl="20" Desc="To get the metadata for a specific module. Specify the API name of the module, such as Leads, Accounts or Deals in your API request."
              Template="NoPagination" HelpLink="https://www.zoho.com/crm/developer/docs/api/modules-api.html">
      <Params>
        <Param Name="Filter" Type="Property" Desc="Filter for JSON" Value="$.modules[*]" Options="All Modules=$.modules[*];Module Profiles=$.modules[*].profiles[*];" />
        <Param Name="module" Required="True" Type="Query" Desc="Module name for which you like to get settings" Value=""
                       OptionsEndPoint="get_modules" OptionsEndPointValueColumn="api_name" OptionsEndPointLabelColumn="module_name"
                       Options="Accounts;Activities;Calls;Campaigns;Cases;Contacts;Deals;Events;Invoices;Leads;Price_Books;Products;Purchase_Orders;Quotes;Sales_Orders;Solutions;Tasks;Vendors;Your_Custom_Module_Name;"
               />
      </Params>
    </EndPoint>

    <EndPoint Name="get_tags" Group="Tags" Label="List Tags" Url="/settings/tags?per_page=2000" Cached="True" CachedTtl="20"
              Desc="List tags for module."
              Filter="$.tags[*]"
              Template="NoPagination" HelpLink="https://www.zoho.com/crm/developer/docs/api/v2/get-tag-list.html"
      >
      <Params>
        <Param Name="module" Required="True" Type="Query" Desc="Module name for which you like to get settings" Value=""
                       OptionsEndPoint="get_modules" OptionsEndPointValueColumn="api_name" OptionsEndPointLabelColumn="module_name"
                       Options="Accounts;Activities;Calls;Campaigns;Cases;Contacts;Deals;Events;Invoices;Leads;Price_Books;Products;Purchase_Orders;Quotes;Sales_Orders;Solutions;Tasks;Vendors;Your_Custom_Module_Name;"
               />
      </Params>
      <OutputColumns>
        <Column Name="id" Label="Id" DataType="DT_WSTR" Length="25" />
        <Column Name="name" Label="Name" DataType="DT_WSTR" Length="255" />
        <Column Name="created_by.id" Label="Created_By_Id" DataType="DT_WSTR" Length="25" />
        <Column Name="created_by.name" Label="Created_By_Name" DataType="DT_WSTR" Length="255" />


        <Column Name="created_time" Label="Created_Time" DataType="DT_DBTIMESTAMP" />
        <Column Name="modified_time" Label="Modified_Time" DataType="DT_DBTIMESTAMP" />
      </OutputColumns>
    </EndPoint>

    <EndPoint Name="get_tag_record_count" Group="Tags" Label="Gets record count for specific tag for module" 
              Url="/settings/tags/[$tag_id$]/actions/records_count"
              Desc="Add tags for specified module and specified record id(s)."
              Template="NoPagination" HelpLink="https://www.zoho.com/crm/developer/docs/api/v2/add-tags.html"
      >
      <Params>
        <Param Name="module" Type="Query" Required="True" Desc="Module name for which you like to get settings"
                       OptionsEndPoint="get_modules" OptionsEndPointValueColumn="api_name" OptionsEndPointLabelColumn="module_name"
                       Options="Accounts;Activities;Calls;Campaigns;Cases;Contacts;Deals;Events;Invoices;Leads;Price_Books;Products;Purchase_Orders;Quotes;Sales_Orders;Solutions;Tasks;Vendors;Your_Custom_Module_Name;"
               />
        <Param Name="tag_id" Required="True" Label="Tag Id" Desc="Use List Tags to findout Id for tag you like to query"
        OptionsEndPoint="get_module_tags" OptionsEndPointValueColumn="Id" OptionsEndPointLabelColumn="Name" OptionsEndPointParameters="module=[$module$]"        
      />
      </Params>
      <OutputColumns>
        <Column Name="count" Label="Count" DataType="DT_I8" />
      </OutputColumns>
    </EndPoint>

    <EndPoint Name="post_tags" Group="Tags" Label="Add / Update Tags for records" Url="[$module$]/actions/add_tags"
              Desc="Add tags for specified module and specified record id(s)."
              Filter="$.data[*]"
              Method="POST"
              MultiSelectSeparator=","
              Template="CRUD" HelpLink="https://www.zoho.com/crm/developer/docs/api/v2/add-tags.html"
      >
      <Params>
        <Param Name="module" Required="True" Desc="Module name for which you like to get settings" Value=""
                       OptionsEndPoint="get_modules" OptionsEndPointValueColumn="api_name" OptionsEndPointLabelColumn="module_name"
                       Options="Accounts;Activities;Calls;Campaigns;Cases;Contacts;Deals;Events;Invoices;Leads;Price_Books;Products;Purchase_Orders;Quotes;Sales_Orders;Solutions;Tasks;Vendors;Your_Custom_Module_Name;"
               />
        <Param Name="ids" Type="Query" Required="True" Label="Record Id(s) (comma seperated list)" Desc="List of Record Id(s) you like to update" />
        <Param Name="tag_names" Type="Query" Required="True" Label="Tag Id" Desc="List of Tag(s) you like to add"
          MultiSelect="True" OptionsEndPoint="get_module_tags" OptionsEndPointValueColumn="Name" OptionsEndPointLabelColumn="Name" OptionsEndPointParameters="module=[$module$]" />      
        <Param Name="over_write" Label="Overwrite" Type="Query" Desc="Set this to overwrite exising tags for the record(s)" Options=";true;false"/>
      </Params>
      <OutputColumns>
        <Column Name="details.tags" Label="tags" DataType="DT_WSTR" Length="1000" Raw="True"/>
      </OutputColumns>
    </EndPoint>

    <EndPoint Name="get_module_fields" Label="List Module Fields" Url="/settings/fields" Template="NoPagination"
          Cached="True" CachedTtl="60" UseRawCache="True"
          Desc="To get the field meta data for the specified module. The fields displayed are from all layouts for the module and the response does not contain layout-specific fields like mandatory fields or picklist values.">
      <Params>
        <Param Name="module" Required="True" Type="Query" Desc="Module name for which you like to get all fields" Value=""
               OptionsEndPoint="get_modules" OptionsEndPointValueColumn="api_name" OptionsEndPointLabelColumn="module_name"
               Options="Accounts;Activities;Calls;Campaigns;Cases;Contacts;Deals;Events;Invoices;Leads;Price_Books;Products;Purchase_Orders;Quotes;Sales_Orders;Solutions;Tasks;Vendors;Your_Custom_Module_Name;"
               />
        <Param Name="Filter" Type="Property" Desc="Filter for JSON" Value="$.fields[*]"
               Options="All Fields=$.fields[*];Custom Fields=$.fields[?(@custom_field==true)];System defined fields=$.fields[?(@custom_field==false)];Fields which are not readonly=$.fields[?(@read_only==false)];Readonly fields=$.fields[?(@read_only==true)]" />
      </Params>
    </EndPoint>

    <EndPoint Name="get_module_views" Label="List Views" Url="/settings/custom_views" Template="NoPagination" Cached="True" CachedTtl="60" >
      <Params>
        <Param Name="module" Required="True" Type="Query" Desc="Module name for which you like to get all views" Value=""
               OptionsEndPoint="get_modules" OptionsEndPointValueColumn="api_name" OptionsEndPointLabelColumn="module_name"
               />
        <Param Name="Filter" Type="Property" Desc="Filter for JSON" Value="$.custom_views[*]" Options="All Views=$.custom_views[*];System defined views only=$.custom_views[?(@system_defined==true)];User defined views only=$.custom_views[?(@system_defined==false)]" />
      </Params>
    </EndPoint>

    <EndPoint Name="get_[$parent.api_name$]" Label="Read [$parent.module_name$]" Group="[$parent.api_name$]" 
		Expand="True" Template="ModulePagination" DataEndPoint="get_modules"
              ResponseFormat="Json" Url="[$parent.api_name$]"
              HelpLink="https://www.zoho.com/crm/developer/docs/api/v2/get-records.html"
			  Desc="This endpoint reads records using bulk approach. Default API Version is V2 (set connection level) and its almost 2 times faster than higher API version (e.g. V3+) but V2 may return less number of columns compared to new API versions (e.g. v3...v7+). API V2 makes less number of requests and returns more records per call (200 rows), on the other side V3+ has limits of max 50 fields in each Get Records API calls. To avoid this limitation in V3+ API we used /{module}?ids={150 ids} workaround but this is still slower compred to older API (v2) approach. Choose new API if you have a valid reason (e.g. you need additional new columns exposed in v3+) else stick with older version V2 (its default setting)"
			  >
      <Params>
		<Param Name="Module" Value="[$parent.api_name$]" Hidden="True" PushToChildEndPoint="True"/>
        <Param Name="If-Modified-Since" Type="Header"
               Label="Last Modified Date - Read data modified after it" Desc="Supply this DateTime (ISO 8601 format) - To get the list of recently modified records"
               Value="1900-12-31T00:00:00" Functions="FUN_TO_UTC_DATE" Editor="DateTime" />

        <Param Name="cvid" Type="Query" Label="Custom View ID" Desc="To get the list of records based on custom views."
            OptionsEndPoint="get_module_views" OptionEndPointParameters="module=[$parent.api_name$];"
            OptionsEndPointValueColumn="id" OptionsEndPointLabelColumn="display_value" />

		<Param Name="DisableChildEndPoint" Type="Property" PropertyScope="EndPoint" Value="True" ValueTemplate="&lt;&lt;[$Version$]|~|Eq|~|v2|~|True|~|False,FUN_IF&gt;&gt;" />
		
		<Param Name="FieldsValue" Type="Property" PropertyScope="Parameter" Key="fields.Value" 
			Value="id" ValueTemplate="&lt;&lt;[$Version$]|~|Eq|~|v2|~||~|id,FUN_IF&gt;&gt;" />
	
        <Param Name="fields" Label="Fields (Only for V2 API)" Type="Query" Desc="To retrieve specific field values. Kepp blank to get all fields."
            OptionsEndPoint="get_module_fields" OptionEndPointParameters="module=[$parent.api_name$];"
            OptionsEndPointValueColumn="api_name" 
			MultiSelect="True" 
			MultiSelectSeparator="," 
			MultiSelectAllOnBlank="False"
			MultiSelectLimit="0"
			ValueTemplate="&lt;&lt;[$Version$]|~|Eq|~|v2|~|{$value$}|~|id,FUN_IF&gt;&gt;"
			/>

        <Param Name="sort_by" Type="Query" Desc="Specify the field name based on which the records must be sorted."
            OptionsEndPoint="get_module_fields" OptionEndPointParameters="module=[$parent.api_name$];"
            OptionsEndPointValueColumn="api_name" />
        <Param Name="sort_order" Type="Query" Desc="To sort the list of records in either ascending or descending order." Options=";asc;desc" />
        <Param Name="territory_id" Type="Query" Desc="To get the list of records in a territory. Use get_territories endpoint to list Id and names."  />
        <Param Name="include_child" Type="Query" Desc="To include records from the child territories. Default is false."  Options=";true;false"/>
        <Param Name="converted" Type="Query" Desc="converted"  Options=";true;false;both"/>
      
	    <Param Name="PagingMode" Type="Property" Value="ByUrlParameter" ValueTemplate="&lt;&lt;[$Version$]|~|Eq|~|v2|~|ByUrlParameter|~|ByResponseAttribute,FUN_IF&gt;&gt;"  />
		<Param Name="NextUrlAttributeOrExpr" Type="Property" Value="$.info.next_page_token" ValueTemplate="&lt;&lt;[$Version$]|~|Eq|~|v2|~||~|{$value$},FUN_IF&gt;&gt;" />
		<Param Name="NextUrlSuffix" Type="Property" Value="page_token=&lt;%nextlink%&gt;" ValueTemplate="&lt;&lt;[$Version$]|~|Eq|~|v2|~||~|{$value$},FUN_IF&gt;&gt;" />		      	  
	  
	  </Params>
      <OutputColumns>
        <Column Name="id" Label="Id" DataType="DT_WSTR" Length="25" Order="-2" />
      </OutputColumns>
	  
	  <EndPoint Name="child_search" RequestFormat="Csv" 
		Url="/[$Module$]?ids={$rows$}" 
		BatchSize="150" Filter="$.data[*]">
		<LayoutMap>
			<![CDATA[<?xml version="1.0" encoding="utf-8"?> 
			<settings> 
				<dataset id="root" readfrominput="True" /> 
				<map name="id" src="id" /> 
			</settings> 
			]]>
		</LayoutMap>
	   </EndPoint> 	  
    </EndPoint>
	
    <EndPoint Name="get_[$parent.api_name$]_fast" Label="Read [$parent.module_name$] (Use this for fewer than 50 Fields in v3+)" 
		Desc="Use this endpoint if you have fewer than 50 fields and you like to utilize newer APi e.g. V3+, If you calling older API V2 then you can use any endpoint (e.g. get_contacts or get_contacts_fast or Contacts table all yeilds same speed in V2)."
		Group="[$parent.api_name$]" 
		Expand="True" Template="ModulePagination" DataEndPoint="get_modules"
              ResponseFormat="Json" Url="[$parent.api_name$]"
              HelpLink="https://www.zoho.com/crm/developer/docs/api/v2/get-records.html">
      <Params>
		<Param Name="Module" Value="[$parent.api_name$]" Hidden="True" PushToChildEndPoint="True"/>
        <Param Name="If-Modified-Since" Type="Header"
               Label="Last Modified Date - Read data modified after it" Desc="Supply this DateTime (ISO 8601 format) - To get the list of recently modified records"
               Value="1900-12-31T00:00:00" Functions="FUN_TO_UTC_DATE" Editor="DateTime" />

        <Param Name="cvid" Type="Query" Label="Custom View ID" Desc="To get the list of records based on custom views."
            OptionsEndPoint="get_module_views" OptionEndPointParameters="module=[$parent.api_name$];"
            OptionsEndPointValueColumn="id" OptionsEndPointLabelColumn="display_value" />

		<Param Name="FieldsMultiSelectAllOnBlank" Type="Property" PropertyScope="Parameter" Value="False" Key="fields.MultiSelectAllOnBlank" 
			ValueTemplate="&lt;&lt;[$Version$]|~|Eq|~|v2|~|False|~|True,FUN_IF&gt;&gt;" />
			
		<Param Name="FieldsMultiSelectLimit" Type="Property" PropertyScope="Parameter" Value="0" Key="fields.MultiSelectLimit" 
			ValueTemplate="&lt;&lt;[$Version$]|~|Eq|~|v2|~|0|~|50,FUN_IF&gt;&gt;" />
		
		<ParamZZZ Name="FieldsValue" Type="Property" PropertyScope="Parameter" Key="fields.Value" 
			Value="id" ValueTemplate="&lt;&lt;[$Version$]|~|Eq|~|v2|~||~|id,FUN_IF&gt;&gt;" />
	
        <Param Name="fields" Label="Fields (Only for V2 API)" Type="Query" Desc="To retrieve specific field values. Kepp blank to get all fields."
            OptionsEndPoint="get_module_fields" OptionEndPointParameters="module=[$parent.api_name$];"
            OptionsEndPointValueColumn="api_name" 
			MultiSelect="True" 
			MultiSelectSeparator="," 
			MultiSelectAllOnBlank="False"
			MultiSelectLimit="0"
			ValueTemplateZZZZ="&lt;&lt;[$Version$]|~|Eq|~|v2|~|{$value$}|~|id,FUN_IF&gt;&gt;"
			/>

        <Param Name="sort_by" Type="Query" Desc="Specify the field name based on which the records must be sorted."
            OptionsEndPoint="get_module_fields" OptionEndPointParameters="module=[$parent.api_name$];"
            OptionsEndPointValueColumn="api_name" />
        <Param Name="sort_order" Type="Query" Desc="To sort the list of records in either ascending or descending order." Options=";asc;desc" />
        <Param Name="territory_id" Type="Query" Desc="To get the list of records in a territory. Use get_territories endpoint to list Id and names."  />
        <Param Name="include_child" Type="Query" Desc="To include records from the child territories. Default is false."  Options=";true;false"/>
        <Param Name="converted" Type="Query" Desc="converted"  Options=";true;false;both"/>
      
	    <Param Name="PagingMode" Type="Property" Value="ByUrlParameter" ValueTemplate="&lt;&lt;[$Version$]|~|Eq|~|v2|~|ByUrlParameter|~|ByResponseAttribute,FUN_IF&gt;&gt;"  />
		<Param Name="NextUrlAttributeOrExpr" Type="Property" Value="$.info.next_page_token" ValueTemplate="&lt;&lt;[$Version$]|~|Eq|~|v2|~||~|{$value$},FUN_IF&gt;&gt;" />
		<Param Name="NextUrlSuffix" Type="Property" Value="page_token=&lt;%nextlink%&gt;" ValueTemplate="&lt;&lt;[$Version$]|~|Eq|~|v2|~||~|{$value$},FUN_IF&gt;&gt;" />		      	  
	  
	  </Params>
      <OutputColumns>
        <Column Name="id" Label="Id" DataType="DT_WSTR" Length="25" Order="-2" />
      </OutputColumns>
	   
    </EndPoint>	

    <EndPoint Name="search_[$parent.api_name$]" Group="[$parent.api_name$]" Expand="True" Template="ModulePagination" DataEndPoint="get_modules"
              ResponseFormat="Json" Label="Search [$parent.module_name$]" Url="[$parent.api_name$]/search" Desc="Search records by criteria or email or phone or word or id (specify only one parameter for search and keep other blank)"
              HelpLink="https://www.zoho.com/crm/developer/docs/api/v2/search-records.html">
      <Params>
        <Param Name="criteria" Type="Query" 
               Label="Search By Criteria Expression" 
               Desc="You can supply upto 10 criterias. For more complex expression use Query API. Example: ((Last_Name:equals:Burns)and(First_Name:starts_with:Ma)). You can lookup row by ID like (id:equals:1458554000067017001). Here is Syntax for expression (({api_name}:{starts_with|equals|in|between|not_equal|greater_equal|less_equal}:{value})and/or({api_name}:{starts_with|equals|in|between|not_equal|greater_equal|less_equal}:{value})) " 
               Options="None=;Example of Equal=(id:equal:11223344);
               Example NOT EQUAL=(id:not_equal:11223344);
               Example OR (multiple conditions)=(id:equal:1111111)or(id:equal:222222222);
               Example IN=(id:in:1111111,222222222,333333333);
               Example START_WITH=(Last_Name:starts_with:pat);
               Example BETWEEN=(Created_Time:between:2024-02-01T18:52:56+00:00,2024-02-20T18:52:56+00:00)"
        />
        <Param Name="email" Type="Query" Label="Search By Email"  />
        <Param Name="phone" Type="Query" Label="Search By Phone"   />
        <Param Name="word" Type="Query" Label="Search By any Word" />
        <Param Name="id" Type="Query" Label="Search By Id" Key="criteria" ValueTemplate="id:equals:{$value$}" IsKey="True"/>
        <Param Name="converted" Type="Query" Options=";true;false;both" Label="Include only converted records" />
        <Param Name="approved" Type="Query" Options=";true;false;both" Value="both" Label="Include approved records" />
      </Params>
      <OutputColumns>
        <Column Name="id" Label="Id" DataType="DT_WSTR" Length="25" Order="-2" />
      </OutputColumns>
    </EndPoint>

    <EndPoint Name="delete_[$parent.api_name$]" Group="[$parent.api_name$]" Expand="True" Template="CRUD" DataEndPoint="get_modules"
              RequestFormat="Csv" ResponseFormat="Json" Label="Delete [$parent.module_name$]" Url="[$parent.api_name$]?ids=[$id$]" Method="DELETE"
              HelpLink="https://www.zoho.com/crm/developer/docs/api/v2/delete-records.html" Filter="$.data[*]" BatchSize="100">
      <Params>
        <Param Name="id" Label="Record ID(s) - Use Comma for multiple (e.g. 111,222)" IsKey="True" Required="True" Functions="{$rows$}"/>
        <Param Name="wf_trigger" Type="Query" Label="Fire Wordflow Trigger" Options=";true;false"/>
      </Params>

      <InputColumns>
        <Column Name="id" MapToParam="True" DataType="DT_WSTR" Length="50" Key="True"/>
      </InputColumns>

    </EndPoint>

    <EndPoint Name="post_[$parent.api_name$]" Group="[$parent.api_name$]" Expand="True" Template="CRUD" DataEndPoint="get_modules"
              Label="Insert [$parent.module_name$]" Url="[$parent.api_name$]" Method="POST"
      Filter="$.data[*]" BatchSize="100"  ContentType="application/json">

      <Body>
        <![CDATA[{
  "data": {$rows$},
  "trigger": [[$Triggers$]]
}]]>
      </Body>
      <Params>
        <Param Name="Triggers" Value="&quot;approval&quot;,&quot;workflow&quot;,&quot;blueprint&quot;"/>
      </Params>
      <OutputColumns>
        <Column Name="details.expected_data_type" Label="expected_data_type" DataType="DT_WSTR" Length="255" />
        <Column Name="details.api_name" Label="api_name" DataType="DT_WSTR" Length="255" />
        <Column Name="details.Created_Time" Label="created_time" DataType="DT_DBTIMESTAMP" />
        <Column Name="details.Modified_Time" Label="modified_time" DataType="DT_DBTIMESTAMP" />
        <Column Name="details.Modified_By.name" Label="modified_by_name" DataType="DT_WSTR" Length="255" />
        <Column Name="details.Modified_By.id" Label="modified_by_id" DataType="DT_WSTR" Length="255" />
        <Column Name="details.Created_By.name" Label="created_by_name" DataType="DT_WSTR" Length="255" />
        <Column Name="details.Created_By.id" Label="created_by_id" DataType="DT_WSTR" Length="255" />
      </OutputColumns>

      <InputColumns>
        <Column Name="-Dynamic-" Expand="True" DataEndPoint="get_module_fields" DataEndPointParameters="module=[$parent.api_name$];Filter=$.fields[?(@read_only==false)];"
                ColumnInfoMap="Name=api_name;DataType=data_type;Length=length;Raw=json_type"
                RawInfoMap="jsonobject;jsonarray"
                DataTypeMap="DT_BOOL=boolean;DT_I8=bigint;DT_I4=integer;DT_WSTR=profileimage,ownerlookup,text,picklist,phone,website,lookup;DT_DBTIMESTAMP=datetime,date;DT_R8=currency,double;DT_NTEXT=textarea"
                />
      </InputColumns>
    </EndPoint>

    <EndPoint Name="put_[$parent.api_name$]" Group="[$parent.api_name$]" Expand="True" Template="CRUD" DataEndPoint="get_modules"
               Label="Update [$parent.module_name$]" Url="[$parent.api_name$]" Method="PUT"
       Filter="$.data[*]" BatchSize="100"  ContentType="application/json">

      <Body>
        <![CDATA[{
  "data": {$rows$},
  "trigger": [[$Triggers$]]
}]]>
      </Body>
      <Params>
        <Param Name="Triggers" Value="&quot;approval&quot;,&quot;workflow&quot;,&quot;blueprint&quot;"/>
      </Params>
      <OutputColumns>
        <Column Name="details.expected_data_type" Label="expected_data_type" DataType="DT_WSTR" Length="255" />
        <Column Name="details.api_name" Label="api_name" DataType="DT_WSTR" Length="255" />
        <Column Name="details.Created_Time" Label="created_time" DataType="DT_DBTIMESTAMP" />
        <Column Name="details.Modified_Time" Label="modified_time" DataType="DT_DBTIMESTAMP" />
        <Column Name="details.Modified_By.name" Label="modified_by_name" DataType="DT_WSTR" Length="255" />
        <Column Name="details.Modified_By.id" Label="modified_by_id" DataType="DT_WSTR" Length="255" />
        <Column Name="details.Created_By.name" Label="created_by_name" DataType="DT_WSTR" Length="255" />
        <Column Name="details.Created_By.id" Label="created_by_id" DataType="DT_WSTR" Length="255" />
      </OutputColumns>

      <InputColumns>
        <Column Name="id" DataType="DT_WSTR" Length="25" Key="True" />
        <Column Name="-Dynamic-" Expand="True" DataEndPoint="get_module_fields" DataEndPointParameters="module=[$parent.api_name$];Filter=$.fields[?(@read_only==false)];"
                ColumnInfoMap="Name=api_name;DataType=data_type;Length=length;Raw=json_type"
                RawInfoMap="jsonobject;jsonarray"
                DataTypeMap="DT_BOOL=boolean;DT_I8=bigint;DT_I4=integer;DT_WSTR=profileimage,ownerlookup,text,picklist,phone,website,lookup;DT_DBTIMESTAMP=datetime,date;DT_R8=currency,double;DT_NTEXT=textarea"
                />
      </InputColumns>
    </EndPoint>

    <EndPoint Name="upsert_[$parent.api_name$]" Group="[$parent.api_name$]" Expand="True" Template="CRUD" DataEndPoint="get_modules"
               Label="Upsert [$parent.module_name$] (Update or Insert)" Url="[$parent.api_name$]/upsert" Method="POST"
       Filter="$.data[*]" BatchSize="100" ContentType="application/json">

      <Body>
        <![CDATA[{
  "data": {$rows$},
  "trigger": [[$Triggers$]],
  "duplicate_check_fields": [[$Duplicate_Check_Fields$]]
}]]>
      </Body>
      <Params>
        <Param Name="Triggers" Value="&quot;approval&quot;,&quot;workflow&quot;,&quot;blueprint&quot;"/>
        <Param Name="Duplicate_Check_Fields" Value="Email" MultiSelect="True" MultiSelectSeparator="," MultiSelectTemplate="&quot;{@value}&quot;" Options="By Email=Email;By Phone=Phone;By Mobile=Mobile"/>

      </Params>
      <OutputColumns>
        <Column Name="duplicate_field" DataType="DT_WSTR" Length="255" />
        <Column Name="details.expected_data_type" Label="expected_data_type" DataType="DT_WSTR" Length="255" />
        <Column Name="details.api_name" Label="api_name" DataType="DT_WSTR" Length="255" />		
        <Column Name="details.Modified_Time" Label="modified_time" DataType="DT_DBTIMESTAMP" />
        <Column Name="details.Modified_By.name" Label="modified_by_name" DataType="DT_WSTR" Length="255" />
        <Column Name="details.Modified_By.id" Label="modified_by_id" DataType="DT_WSTR" Length="255" />
        <Column Name="details.Created_Time" Label="created_time" DataType="DT_DBTIMESTAMP" />
        <Column Name="details.Created_By.name" Label="created_by_name" DataType="DT_WSTR" Length="255" />
        <Column Name="details.Created_By.id" Label="created_by_id" DataType="DT_WSTR" Length="255" />
      </OutputColumns>

      <InputColumns>
        <Column Name="-Dynamic-" Expand="True" DataEndPoint="get_module_fields" DataEndPointParameters="module=[$parent.api_name$];Filter=$.fields[?(@read_only==false)];"
                ColumnInfoMap="Name=api_name;DataType=data_type;Length=length;Raw=json_type"
                RawInfoMap="jsonobject;jsonarray"
                DataTypeMap="DT_BOOL=boolean;DT_I8=bigint;DT_I4=integer;DT_WSTR=profileimage,ownerlookup,text,picklist,phone,website,lookup;DT_DBTIMESTAMP=datetime,date;DT_R8=currency,double;DT_NTEXT=textarea"
                />
      </InputColumns>
    </EndPoint>

  </EndPoints>

  <Tables>
    <Table Name="[$parent.api_name$]" Expand="True" DataEndPoint="get_modules"
      SelectEndPoint="get_[$parent.api_name$]"
      LookupEndPoint="search_[$parent.api_name$]"
      InsertEndPoint="post_[$parent.api_name$]"
      UpdateEndPoint="put_[$parent.api_name$]"
      UpsertEndPoint="upsert_[$parent.api_name$]"
      DeleteEndPoint="delete_[$parent.api_name$]" >
    </Table>
  </Tables>
  <Examples>
    <Example Group="ODBC" Label="Read all rows" Code="SELECT * from Accounts"></Example>

    <Example Group="ODBC" Label="Update Owner of the record(s) - Account, Contacts, Deals, Leads (Update Lookup field)" Desc="This examples shows how to update a lookup type fields (e.g. Account, Contact, Owner) for any module. Lookup fields are jsonobject type of fields which has id, name and sometimes email (only for Owner). This example shows how to update using unique field (E.g. email, id or name). Below example shows how to set Owner of the Account (e.g.) 1558554000137221573. We will set owner to bob-the-salesman@abc.com (or you can set by id)">
      <Code>
        <![CDATA[UPDATE Accounts 
SET Owner='{email: "bob-the-salesman@abc.com"}'
--SET Owner='{id: "1558554000186378001"}' --you can also use Id
Where Id='1558554000137221573']]>
      </Code>
    </Example>
    <Example Group="ODBC" Label="Update Account or Contact (Lookup field) by Name or Id for Deals" Desc="This examples shows how to update Account and Contact field on Deals module. We used name for account and id for contact just to show how unique field can be used.">
      <Code>
        <![CDATA[UPDATE Deals 
SET Account_Name='{"name": "Company ABCD"}',    --by name or id 
    Contact_Name='{"id": "1558554000186378001"}'  --by id 
Where Id='1558554000137221573']]>
      </Code>
    </Example>	

    <Example Group="ODBC" Label="Create a Deal with Lookup fields (e.g. set Account, Contact, Owner etc by Id or Name)" Desc="This examples shows how to create a new record with Lookup field(s) e.g account, contact or owner.">
      <Code>
        <![CDATA[
INSERT INTO Deals(
	Deal_name,
	Amount,
	Lead_Source,
	Account_Name,
	Contact_Name,
	Owner
	)
VALUES
   (
   'My Test Deal Creatyed on <<FUN_NOW>>', --deal name
   1000.50, --amount
   'Cold Call', --lead source
   '{name:"ZappySys"}', --account name or use id '{id:"1558554000030180013"}'
   '{id:"1558554000089352998"}' --contact id 
   '{id:"1558554000089352912"}' --owner id or use email {email: "bob-the-salesman@abc.com"}
   )
		]]>
      </Code>
    </Example>	
	

    <Example Group="ODBC" Label="Read single row by ID" Code="SELECT * from Accounts Where Id=1558554000105110008"></Example>
    <Example Group="ODBC" Label="Read reacord(s) modified after certain date" Code="SELECT * from Accounts WITH(ModifiedSince = '2020-01-07T00:00:00')"></Example>
    <Example Group="ODBC" Label="Read using COQL (Zoho Serverside Query Language)" Desc="You can write server side query so you dont have to read full data on client side. For COQL LIMIT clause must be 200 or less. For more information check this URL https://zappysys.com/links?url=https://www.zoho.com/crm/developer/docs/api/COQL-Overview.html"
             Code="SELECT * from get_module_data_coql WITH(sql_query= 'select Last_Name, First_Name, Company from Leads where Company like ''Test'' limit 200')"></Example>
    <Example Group="ODBC" Label="Update table for specific record" Code="Update Leads SET Designation='VP Sales', Company='Test' Where id=1558554000012181009"></Example>
    <Example Group="ODBC" Label="Update table for specific record (older version)" Code="Update Leads SET id='1558554000012181009' /* id must be supplied */, Designation='VP Sales', Company='Test'"></Example>
    <Example Group="ODBC" Label="Get accounts modified after certain date" Code="SELECT * from Accounts Where Account_Name LIKE 'Test%' WITH(ModifiedSince = '2020-01-07T00:00:00')"></Example>
    <Example Group="ODBC" Label="Search accounts by specific field (server side filter)"
             Desc="You can use criteria listed here https://www.zoho.com/crm/developer/docs/api/v2/search-records.html"
             Code="SELECT * FROM search_Accounts WITH(criteria='Account_Name:starts_with:test')"></Example>

    <Example Group="ODBC" Label="Create a new record" Code="INSERT INTO Accounts(Account_Name, Phone) VALUES('Company ABC','111-567-8888')"></Example>
    <Example Group="ODBC" Label="Create a new account record (with show output on / off)" Code="INSERT INTO Accounts(Account_Name, Phone) VALUES('Company ABC','111-567-8888') WITH(Output=1) "></Example>
    <Example Group="ODBC" Label="Delete single record by Id" Desc="Delete exising record by Id (single row). You can supply upto 100 comma seperated Ids" Code="DELETE FROM Accounts WHERE id=11111111111"></Example>

    <Example Group="ODBC" Label="Delete multiple records by Ids" Desc="This example shows how to delete Account Records by multiple Ids. You can supply upto 100 comma seperated Ids" Code="DELETE FROM Accounts WITH(Id='11111,22222,33333')"></Example>

	
    <Example Group="ODBC" Label="Upsert account record (Update or Insert - based on unique field(s) for module)" Code="UPSERT INTO Accounts(Account_Name, Phone) VALUES('Company ABC','111-567-8888') WITH(Output=1)"></Example>
	
    <Example Group="ODBC" Label="Upsert lead record (Update or Insert - based on unique field(s) for module)" Code="UPSERT INTO Leads(Last_Name, Email) VALUES('Patel','zpatel@abc.com') WITH(Output=1)"></Example>	

    <Example Group="ODBC" Label="Create new account(s) in BULK (read / write from external source)" Desc="This examples shows how to use SOURCE clause to read data from MS SQL Server (or other external system) and send data to Zoho using Bulk API">
      <Code>
        <![CDATA[INSERT INTO Accounts
SOURCE(
  'MSSQL' --ODBC or OLEDB
  ,'Data Source=localhost;Initial Catalog=Test;Integrated Security=true'
  ,'select ''Test Account-A'' as Account_Name,''111-111-1111'' as Phone
    UNION
    select ''Test Account-B'' as Account_Name,''222-222-2222'' as Phone
   '
)]]>
      </Code>
    </Example>

    <Example Group="ODBC" Label="UPSERT (Update or insert) account(s) in BULK (read / write from external source)" Desc="This examples shows how to use SOURCE clause to read data from MS SQL Server (or other external system) and send data to Zoho using Bulk API. Record uniqueness is checked based on Unique field setup for module (i.e. email, account name, phone etc)">
      <Code>
        <![CDATA[UPSERT INTO Accounts
SOURCE(
  'MSSQL' --ODBC or OLEDB
  ,'Data Source=localhost;Initial Catalog=Test;Integrated Security=true'
  ,'select ''Test Account-A'' as Account_Name,''111-111-1111'' as Phone
    UNION
    select ''Test Account-B'' as Account_Name,''222-222-2222'' as Phone
   '
)]]>
      </Code>
    </Example>

    <Example Group="ODBC" Label="Update Tag(s) for exising records (add or overwrite)" >
      <Code>
        <![CDATA[SELECT * FROM post_tags
WITH(
	  module='Accounts'
	, ids='1558554000105151002'
	, tag_names='mytag1,mytag2'
  , over_write='true'
)]]>
      </Code>
    </Example>
  </Examples>
</ApiConfig>