<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://sugarclub.sugarai.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>Integrations for Devs</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs</link><description /><dc:language>en-US</dc:language><generator>Telligent Community 12</generator><item><title>Integrations for Devs</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs</link><pubDate>Wed, 10 Sep 2025 15:09:03 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:df5ca10a-d211-4e03-9873-9d48feb7b645</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs#comments</comments><description>Current Revision posted to Dev Tutorials by Rafael Fernandes on 9/10/2025 3:09:03 PM&lt;br /&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="#approach"&gt;&lt;img alt=" " src="/resized-image/__size/269x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.42.25-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#rest"&gt;&lt;img alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.33-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#common"&gt;&lt;img alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.48-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#performance"&gt;&lt;img alt=" " src="/resized-image/__size/268x140/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.44.04-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="approach"&gt;&lt;/a&gt;Integration Approaches&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;The Sugar platform is extremely powerful, flexible, and allows for easy integration. This flexibility means that determining the&amp;nbsp;best approach for your use case scenario is the key to success.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/269x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.42.25-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Push/Pull from Sugar via REST API&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="text-decoration:underline;"&gt;Recommended&lt;/span&gt; approach&lt;/li&gt;
&lt;li&gt;Developers have full control over integration&lt;/li&gt;
&lt;li&gt;Integration can be stopped and systems will continue to work&lt;/li&gt;
&lt;li&gt;Retry mechanism: Resume integrations at any time (identify deltas through &amp;quot;last_update_time&amp;quot; flags)&lt;/li&gt;
&lt;li&gt;The time delay from/to Sugar is minimal&lt;/li&gt;
&lt;li&gt;Sugar REST API offers almost everything you need,&amp;nbsp;and can be further extended via customization&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Push to Sugar, Sugar pushes to an external queue in realtime&lt;span&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;Use Sugar Events to trigger through Logic Hooks&lt;/li&gt;
&lt;li&gt;Requires&amp;nbsp;Logic Hooks (code customization) to be created and deployed&lt;/li&gt;
&lt;li&gt;Does not offer a &amp;quot;retry mechanism&amp;quot;, if a logic hook fails to deliver to a queue or contact an external system&lt;/li&gt;
&lt;li&gt;Synchronous in nature, requires a response from an external system&lt;/li&gt;
&lt;li&gt;Needs to handle dependencies manually (contact can only be created after account)&lt;/li&gt;
&lt;li&gt;Good to have a middleware/queue in front of Sugar to receive those event triggers to&amp;nbsp;reliably&amp;nbsp;manage peak loads&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Realtime: Embed your app into Sugar&amp;nbsp;through &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/User_Interface/Dashlets/"&gt;Dashlets&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Simplest approach&lt;/li&gt;
&lt;li&gt;Often requires web user-based authentication&lt;/li&gt;
&lt;li&gt;All load/traffic goes directly to your system,&amp;nbsp;which makes your system the performance bottleneck&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="rest"&gt;&lt;/a&gt;REST API Webservices&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Accessing your data when you want is good. Accessing your data however you want is better. &lt;/span&gt;&lt;span&gt;When you decide to build an integration with Sugar, you&amp;rsquo;ll need an easy way to access and interact with the data stored in Sugar. The REST (&lt;/span&gt;&lt;span&gt;representational state transfer)&lt;/span&gt;&lt;span&gt;&amp;nbsp;API (application programming interface) is perfect for this.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;You can also leverage our&amp;nbsp;live&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="https://rest.apidocs.sugarcrm.com/"&gt;Sugar RESTful API Collection&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sugar REST API Overview
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;Fully RESTfull (GET, POST, PUT, DELETE)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;OAuth2 token based&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;All fields and modules are available through the API automatically&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Metadata API provides everything you need to know about your Sugar instance.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.33-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Topics
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/new-tutorial-intro-to-the-sugar-rest-api"&gt;Intro to the Sugar REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/how-sugar-rest-api-versioning-works"&gt;How Sugar REST API versioning works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/"&gt;RestAPI Developer Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/sugarcrm-cookbook---the-school-of-rest---part-1"&gt;School of REST blog series&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/"&gt;REST APIs Endpoints&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Extending_Endpoints/"&gt;How to add your own custom endpoints to the REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/API_Exceptions/"&gt;API Exceptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Best_Practices/"&gt;Best practices when integrating and migrating Sugar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="common"&gt;&lt;/a&gt;Common&amp;nbsp;APIs&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;It is important to understand our most commonly used APIs and their functions within Sugar. Your integration might need data within Sugar&amp;#39;s module structure that could potentially change over time, so you can use Metadata for it as well as CRUD onto Sugar.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.48-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Metadata
&lt;ul&gt;
&lt;li&gt;Endpoint with current system&amp;#39;s structure&lt;/li&gt;
&lt;li&gt;Modules, fields, relationships, layouts&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Use carefully, its payload can be MBs in size, cache as much as possible&lt;/li&gt;
&lt;li&gt;GET /metadata (use filters as much as possible)&lt;/li&gt;
&lt;li&gt;It does not retrieve labels for dropdowns, use language API to do so&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/3-tips-for-using-the-sugar-metadata-api"&gt;3 Tips for using the Sugar Metadata API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Language
&lt;ul&gt;
&lt;li&gt;Endpoint to retrieve labels&lt;/li&gt;
&lt;li&gt;Dropdown list values&lt;/li&gt;
&lt;li&gt;Any language-specific content&lt;/li&gt;
&lt;li&gt;GET /lang/&amp;lt;language_code&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CRUD (Create, Read, Update, Delete) records
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulerecord_GET"&gt;Read&lt;/a&gt;: &lt;code&gt;GET /&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/module_POST"&gt;Create&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulerecord_PUT"&gt;Update&lt;/a&gt;: &lt;code&gt;PUT&amp;nbsp;&lt;span&gt;/&amp;lt;module&amp;gt;/:record&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulerecord_DELETE"&gt;Delete&lt;/a&gt;: &lt;code&gt;DELETE&amp;nbsp;/&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulefilter_POST"&gt;Filter&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;/filter&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;You can use &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulefilter_GET"&gt;GET&lt;/a&gt; as well&lt;/li&gt;
&lt;li&gt;POST solves the issue when a query is too long and hits HTTP limits&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulerecordlinklink_name_GET"&gt;Retrieve records related to another module&lt;/a&gt;:&amp;nbsp;&lt;code&gt;GET /&amp;lt;module&amp;gt;/:record/link/:link_name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulerecordlinklink_nameremote_id_POST"&gt;Creates a relationship to a pre-existing record:&lt;/a&gt;&lt;code&gt; POST /&amp;lt;module&amp;gt;/:record/link/:link_name/:remote_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="performance"&gt;&lt;/a&gt;Performance and Best Practices&lt;/h1&gt;
&lt;div class="row"&gt;
&lt;div class="col-xs-12 col-md-9"&gt;
&lt;p&gt;As you deep dive into Sugar APIs,&amp;nbsp;you will see how easy it is to integrate to pull and push data from and to Sugar and your systems, however, you must consider performance so your integration doesn&amp;#39;t become a bottleneck between those systems.&lt;/p&gt;
&lt;p&gt;You should consider the following guidelines when implementing your integrations:&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/268x140/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.44.04-AM.png" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Use Sugar&amp;#39;s sync_key to link to remote IDs
&lt;ul&gt;
&lt;li&gt;Sugar provides in every module a sync_key field&lt;/li&gt;
&lt;li&gt;sync_key is a unique identifier for that module that links back to your external system&amp;#39;s generated key&lt;/li&gt;
&lt;li&gt;For example, account ID from ERP is AC0001, set sync_key (pass as a parameter in the POST) and sugar will create a record in account with sync_key=AC0001&lt;/li&gt;
&lt;li&gt;Next patch/update, sugar will check &amp;quot;where sync_key=&amp;#39;AC0001&amp;#39;&amp;quot; and update it (it is indexed)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Integrate Upsert APIs
&lt;ul&gt;
&lt;li&gt;Sugar&amp;#39;s &amp;quot;update or insert&amp;quot; API based on sync_key&lt;/li&gt;
&lt;li&gt;Simplifies a common operation - if record exists, update it, otherwise create it (GET followed by a&amp;nbsp;PUT or POST)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_PATCH"&gt;Upsert by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_GET"&gt;Get by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_DELETE"&gt;Delete by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulerecord_idsync_key_field_namesync_key_field_value_PATCH"&gt;Set a sync on existing record (without sync_key)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_POST"&gt;Create relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_DELETE"&gt;Delete relationship based on sync_key&lt;/a&gt;&lt;br /&gt;
&lt;ul&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong data-start="1409" data-end="1418"&gt;Note:&lt;/strong&gt; This endpoint is engineered for maximum performance and omits several ACL and validation checks.&lt;/li&gt;
&lt;li&gt;&lt;strong data-start="1522" data-end="1536"&gt;Important:&lt;/strong&gt; For security reasons, the Upsert API is &lt;strong data-start="1577" data-end="1611"&gt;restricted to Admin users only&lt;/strong&gt;&amp;mdash;non-admin users will be denied access.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Bulk API
&lt;ul&gt;
&lt;li&gt;An endpoint that encapsulates multiple API calls into one single HTTP request&lt;/li&gt;
&lt;li&gt;Requests are executed synchronously (one after the other)&lt;/li&gt;
&lt;li&gt;Reducing network latency between calls&lt;/li&gt;
&lt;li&gt;Combined with Upsert provides the best performance&lt;/li&gt;
&lt;li&gt;Careful not to add too many requests to it&lt;/li&gt;
&lt;li&gt;Start small (5 to 10 requests) and increase until you reach its max capacity&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Polling and filtering time-based with Filter API
&lt;ul&gt;
&lt;li&gt;Integration gateway (or your external system) asks Sugar every X minutes&lt;/li&gt;
&lt;li&gt;Request Filter API using &lt;code&gt;max_num&lt;/code&gt; (max number of records), offset and fields&lt;/li&gt;
&lt;li&gt;The response will provide the data as well as &lt;code&gt;next_offset&lt;/code&gt; (offset can be seen as pagination)&lt;/li&gt;
&lt;li&gt;if &lt;code&gt;next_offset&lt;/code&gt; is -1, no more records to go through&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Initial Data Load into Sugar&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Use Bulk + Upsert to achieve data loads&lt;/li&gt;
&lt;li&gt;Millions&amp;nbsp;of records may take a little while to process, plan ahead (over the weekend)&lt;/li&gt;
&lt;li&gt;Use multi-thread processes to load (for example 20 threads sending 20 bulk upsert requests)&lt;/li&gt;
&lt;li&gt;Careful with&amp;nbsp;&lt;a href="https://support.sugarcrm.com/Resources/Sugar_Cloud_Policy_Guide/#Rate_Limits"&gt;Sugar Cloud rate limits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;It&amp;#39;s always a good idea to let Sugar Support know you&amp;#39;re data loading, they will be considerate.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Understanding PHP limitations&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;PHP is single-threaded with limited resources to process your request&lt;/li&gt;
&lt;li&gt;If you send too much data using bulk, you may run out of memory for that request&lt;/li&gt;
&lt;li&gt;Push to the limits but give some room for PHP to finish the request gracefully&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Pagination for millions of records by using OFFSET will degrade performance
&lt;ul&gt;
&lt;li&gt;We rely on DB to find, sort and limit records&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/swlh/sql-pagination-you-are-probably-doing-it-wrong-d0f2719cc166"&gt;Nice article&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/a&gt;explaining how this works in details&lt;/li&gt;
&lt;li&gt;Instead of offsets, store the last processed ID and use it in the WHERE clause and sort by ID&lt;/li&gt;
&lt;li&gt;Example
&lt;ul&gt;
&lt;li&gt;Instead of: (/v11_25/Leads?max_num=1000&amp;amp;&lt;strong&gt;offset=4619000&lt;/strong&gt;&amp;amp;order_by=id)&lt;/li&gt;
&lt;li&gt;Do this&amp;nbsp;(/v11_25/Leads?&lt;strong&gt;filter=[{"id": {"$gt": &amp;rdquo;&amp;lt;last_id&amp;gt;"}}]&lt;/strong&gt;&amp;amp;max_num=1000&amp;amp;order_by=id)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If you need to add a date, make sure to add it as part of the filter and order&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3 id="mcetoc_1f5uvkqns0"&gt;&lt;span style="font-size:inherit;"&gt;You&amp;#39;re up and running, but don&amp;#39;t stop now - this is just the beginning of your journey. Now it&amp;#39;s time to &lt;a href="/dev-club/dev-onboarding/w/documentation/686/customization-for-devs"&gt;Customizations&lt;/a&gt;.&lt;/span&gt;&lt;/h3&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Integrations for Devs</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs/revision/28</link><pubDate>Thu, 14 Aug 2025 17:27:02 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:df5ca10a-d211-4e03-9873-9d48feb7b645</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs#comments</comments><description>Revision 28 posted to Dev Tutorials by Rafael Fernandes on 8/14/2025 5:27:02 PM&lt;br /&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="#approach"&gt;&lt;img alt=" " src="/resized-image/__size/269x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.42.25-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#rest"&gt;&lt;img alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.33-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#common"&gt;&lt;img alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.48-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#performance"&gt;&lt;img alt=" " src="/resized-image/__size/268x140/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.44.04-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="approach"&gt;&lt;/a&gt;Integration Approaches&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;The Sugar platform is extremely powerful, flexible, and allows for easy integration. This flexibility means that determining the&amp;nbsp;best approach for your use case scenario is the key to success.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/269x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.42.25-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Push/Pull from Sugar via REST API&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="text-decoration:underline;"&gt;Recommended&lt;/span&gt; approach&lt;/li&gt;
&lt;li&gt;Developers have full control over integration&lt;/li&gt;
&lt;li&gt;Integration can be stopped and systems will continue to work&lt;/li&gt;
&lt;li&gt;Retry mechanism: Resume integrations at any time (identify deltas through &amp;quot;last_update_time&amp;quot; flags)&lt;/li&gt;
&lt;li&gt;The time delay from/to Sugar is minimal&lt;/li&gt;
&lt;li&gt;Sugar REST API offers almost everything you need,&amp;nbsp;and can be further extended via customization&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Push to Sugar, Sugar pushes to an external queue in realtime&lt;span&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;Use Sugar Events to trigger through Logic Hooks&lt;/li&gt;
&lt;li&gt;Requires&amp;nbsp;Logic Hooks (code customization) to be created and deployed&lt;/li&gt;
&lt;li&gt;Does not offer a &amp;quot;retry mechanism&amp;quot;, if a logic hook fails to deliver to a queue or contact an external system&lt;/li&gt;
&lt;li&gt;Synchronous in nature, requires a response from an external system&lt;/li&gt;
&lt;li&gt;Needs to handle dependencies manually (contact can only be created after account)&lt;/li&gt;
&lt;li&gt;Good to have a middleware/queue in front of Sugar to receive those event triggers to&amp;nbsp;reliably&amp;nbsp;manage peak loads&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Realtime: Embed your app into Sugar&amp;nbsp;through &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/User_Interface/Dashlets/"&gt;Dashlets&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Simplest approach&lt;/li&gt;
&lt;li&gt;Often requires web user-based authentication&lt;/li&gt;
&lt;li&gt;All load/traffic goes directly to your system,&amp;nbsp;which makes your system the performance bottleneck&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="rest"&gt;&lt;/a&gt;REST API Webservices&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Accessing your data when you want is good. Accessing your data however you want is better. &lt;/span&gt;&lt;span&gt;When you decide to build an integration with Sugar, you&amp;rsquo;ll need an easy way to access and interact with the data stored in Sugar. The REST (&lt;/span&gt;&lt;span&gt;representational state transfer)&lt;/span&gt;&lt;span&gt;&amp;nbsp;API (application programming interface) is perfect for this.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;You can also leverage our&amp;nbsp;live&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="https://rest.apidocs.sugarcrm.com/"&gt;Sugar RESTful API Collection&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sugar REST API Overview
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;Fully RESTfull (GET, POST, PUT, DELETE)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;OAuth2 token based&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;All fields and modules are available through the API automatically&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Metadata API provides everything you need to know about your Sugar instance.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.33-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Topics
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/new-tutorial-intro-to-the-sugar-rest-api"&gt;Intro to the Sugar REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/how-sugar-rest-api-versioning-works"&gt;How Sugar REST API versioning works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/"&gt;RestAPI Developer Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/sugarcrm-cookbook---the-school-of-rest---part-1"&gt;School of REST blog series&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/"&gt;REST APIs Endpoints&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Extending_Endpoints/"&gt;How to add your own custom endpoints to the REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/API_Exceptions/"&gt;API Exceptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Best_Practices/"&gt;Best practices when integrating and migrating Sugar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="common"&gt;&lt;/a&gt;Common&amp;nbsp;APIs&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;It is important to understand our most commonly used APIs and their functions within Sugar. Your integration might need data within Sugar&amp;#39;s module structure that could potentially change over time, so you can use Metadata for it as well as CRUD onto Sugar.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.48-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Metadata
&lt;ul&gt;
&lt;li&gt;Endpoint with current system&amp;#39;s structure&lt;/li&gt;
&lt;li&gt;Modules, fields, relationships, layouts&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Use carefully, its payload can be MBs in size, cache as much as possible&lt;/li&gt;
&lt;li&gt;GET /metadata (use filters as much as possible)&lt;/li&gt;
&lt;li&gt;It does not retrieve labels for dropdowns, use language API to do so&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/3-tips-for-using-the-sugar-metadata-api"&gt;3 Tips for using the Sugar Metadata API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Language
&lt;ul&gt;
&lt;li&gt;Endpoint to retrieve labels&lt;/li&gt;
&lt;li&gt;Dropdown list values&lt;/li&gt;
&lt;li&gt;Any language-specific content&lt;/li&gt;
&lt;li&gt;GET /lang/&amp;lt;language_code&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CRUD (Create, Read, Update, Delete) records
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulerecord_GET"&gt;Read&lt;/a&gt;: &lt;code&gt;GET /&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/module_POST"&gt;Create&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulerecord_PUT"&gt;Update&lt;/a&gt;: &lt;code&gt;PUT&amp;nbsp;&lt;span&gt;/&amp;lt;module&amp;gt;/:record&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulerecord_DELETE"&gt;Delete&lt;/a&gt;: &lt;code&gt;DELETE&amp;nbsp;/&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulefilter_POST"&gt;Filter&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;/filter&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;You can use &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulefilter_GET"&gt;GET&lt;/a&gt; as well&lt;/li&gt;
&lt;li&gt;POST solves the issue when a query is too long and hits HTTP limits&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulerecordlinklink_name_GET"&gt;Retrieve records related to another module&lt;/a&gt;:&amp;nbsp;&lt;code&gt;GET /&amp;lt;module&amp;gt;/:record/link/:link_name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulerecordlinklink_nameremote_id_POST"&gt;Creates a relationship to a pre-existing record:&lt;/a&gt;&lt;code&gt; POST /&amp;lt;module&amp;gt;/:record/link/:link_name/:remote_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="performance"&gt;&lt;/a&gt;Performance and Best Practices&lt;/h1&gt;
&lt;div class="row"&gt;
&lt;div class="col-xs-12 col-md-9"&gt;
&lt;p&gt;As you deep dive into Sugar APIs,&amp;nbsp;you will see how easy it is to integrate to pull and push data from and to Sugar and your systems, however, you must consider performance so your integration doesn&amp;#39;t become a bottleneck between those systems.&lt;/p&gt;
&lt;p&gt;You should consider the following guidelines when implementing your integrations:&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/268x140/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.44.04-AM.png" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Use Sugar&amp;#39;s sync_key to link to remote IDs
&lt;ul&gt;
&lt;li&gt;Sugar provides in every module a sync_key field&lt;/li&gt;
&lt;li&gt;sync_key is a unique identifier for that module that links back to your external system&amp;#39;s generated key&lt;/li&gt;
&lt;li&gt;For example, account ID from ERP is AC0001, set sync_key (pass as a parameter in the POST) and sugar will create a record in account with sync_key=AC0001&lt;/li&gt;
&lt;li&gt;Next patch/update, sugar will check &amp;quot;where sync_key=&amp;#39;AC0001&amp;#39;&amp;quot; and update it (it is indexed)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Integrate Upsert APIs
&lt;ul&gt;
&lt;li&gt;Sugar&amp;#39;s &amp;quot;update or insert&amp;quot; API based on sync_key&lt;/li&gt;
&lt;li&gt;Simplifies a common operation - if record exists, update it, otherwise create it (GET followed by a&amp;nbsp;PUT or POST)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_PATCH"&gt;Upsert by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_GET"&gt;Get by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_DELETE"&gt;Delete by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulerecord_idsync_key_field_namesync_key_field_value_PATCH"&gt;Set a sync on existing record (without sync_key)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_POST"&gt;Create relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_DELETE"&gt;Delete relationship based on sync_key&lt;/a&gt;&lt;br /&gt;
&lt;ul&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Bulk API
&lt;ul&gt;
&lt;li&gt;An endpoint that encapsulates multiple API calls into one single HTTP request&lt;/li&gt;
&lt;li&gt;Requests are executed synchronously (one after the other)&lt;/li&gt;
&lt;li&gt;Reducing network latency between calls&lt;/li&gt;
&lt;li&gt;Combined with Upsert provides the best performance&lt;/li&gt;
&lt;li&gt;Careful not to add too many requests to it&lt;/li&gt;
&lt;li&gt;Start small (5 to 10 requests) and increase until you reach its max capacity&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Polling and filtering time-based with Filter API
&lt;ul&gt;
&lt;li&gt;Integration gateway (or your external system) asks Sugar every X minutes&lt;/li&gt;
&lt;li&gt;Request Filter API using &lt;code&gt;max_num&lt;/code&gt; (max number of records), offset and fields&lt;/li&gt;
&lt;li&gt;The response will provide the data as well as &lt;code&gt;next_offset&lt;/code&gt; (offset can be seen as pagination)&lt;/li&gt;
&lt;li&gt;if &lt;code&gt;next_offset&lt;/code&gt; is -1, no more records to go through&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Initial Data Load into Sugar&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Use Bulk + Upsert to achieve data loads&lt;/li&gt;
&lt;li&gt;Millions&amp;nbsp;of records may take a little while to process, plan ahead (over the weekend)&lt;/li&gt;
&lt;li&gt;Use multi-thread processes to load (for example 20 threads sending 20 bulk upsert requests)&lt;/li&gt;
&lt;li&gt;Careful with&amp;nbsp;&lt;a href="https://support.sugarcrm.com/Resources/Sugar_Cloud_Policy_Guide/#Rate_Limits"&gt;Sugar Cloud rate limits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;It&amp;#39;s always a good idea to let Sugar Support know you&amp;#39;re data loading, they will be considerate.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Understanding PHP limitations&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;PHP is single-threaded with limited resources to process your request&lt;/li&gt;
&lt;li&gt;If you send too much data using bulk, you may run out of memory for that request&lt;/li&gt;
&lt;li&gt;Push to the limits but give some room for PHP to finish the request gracefully&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Pagination for millions of records by using OFFSET will degrade performance
&lt;ul&gt;
&lt;li&gt;We rely on DB to find, sort and limit records&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/swlh/sql-pagination-you-are-probably-doing-it-wrong-d0f2719cc166"&gt;Nice article&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/a&gt;explaining how this works in details&lt;/li&gt;
&lt;li&gt;Instead of offsets, store the last processed ID and use it in the WHERE clause and sort by ID&lt;/li&gt;
&lt;li&gt;Example
&lt;ul&gt;
&lt;li&gt;Instead of: (/v11_25/Leads?max_num=1000&amp;amp;&lt;strong&gt;offset=4619000&lt;/strong&gt;&amp;amp;order_by=id)&lt;/li&gt;
&lt;li&gt;Do this&amp;nbsp;(/v11_25/Leads?&lt;strong&gt;filter=[{"id": {"$gt": &amp;rdquo;&amp;lt;last_id&amp;gt;"}}]&lt;/strong&gt;&amp;amp;max_num=1000&amp;amp;order_by=id)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If you need to add a date, make sure to add it as part of the filter and order&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3 id="mcetoc_1f5uvkqns0"&gt;&lt;span style="font-size:inherit;"&gt;You&amp;#39;re up and running, but don&amp;#39;t stop now - this is just the beginning of your journey. Now it&amp;#39;s time to &lt;a href="/dev-club/dev-onboarding/w/documentation/686/customization-for-devs"&gt;Customizations&lt;/a&gt;.&lt;/span&gt;&lt;/h3&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Integrations for Devs</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs/revision/27</link><pubDate>Fri, 16 May 2025 14:49:22 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:df5ca10a-d211-4e03-9873-9d48feb7b645</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs#comments</comments><description>Revision 27 posted to Dev Tutorials by Rafael Fernandes on 5/16/2025 2:49:22 PM&lt;br /&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="#approach"&gt;&lt;img alt=" " src="/resized-image/__size/269x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.42.25-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#rest"&gt;&lt;img alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.33-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#common"&gt;&lt;img alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.48-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#performance"&gt;&lt;img alt=" " src="/resized-image/__size/268x140/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.44.04-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="approach"&gt;&lt;/a&gt;Integration Approaches&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;The Sugar platform is extremely powerful, flexible, and allows for easy integration. This flexibility means that determining the&amp;nbsp;best approach for your use case scenario is the key to success.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/269x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.42.25-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Push/Pull from Sugar via REST API&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="text-decoration:underline;"&gt;Recommended&lt;/span&gt; approach&lt;/li&gt;
&lt;li&gt;Developers have full control over integration&lt;/li&gt;
&lt;li&gt;Integration can be stopped and systems will continue to work&lt;/li&gt;
&lt;li&gt;Retry mechanism: Resume integrations at any time (identify deltas through &amp;quot;last_update_time&amp;quot; flags)&lt;/li&gt;
&lt;li&gt;The time delay from/to Sugar is minimal&lt;/li&gt;
&lt;li&gt;Sugar REST API offers almost everything you need,&amp;nbsp;and can be further extended via customization&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Push to Sugar, Sugar pushes to an external queue in realtime&lt;span&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;Use Sugar Events to trigger through Logic Hooks&lt;/li&gt;
&lt;li&gt;Requires&amp;nbsp;Logic Hooks (code customization) to be created and deployed&lt;/li&gt;
&lt;li&gt;Does not offer a &amp;quot;retry mechanism&amp;quot;, if a logic hook fails to deliver to a queue or contact an external system&lt;/li&gt;
&lt;li&gt;Synchronous in nature, requires a response from an external system&lt;/li&gt;
&lt;li&gt;Needs to handle dependencies manually (contact can only be created after account)&lt;/li&gt;
&lt;li&gt;Good to have a middleware/queue in front of Sugar to receive those event triggers to&amp;nbsp;reliably&amp;nbsp;manage peak loads&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Realtime: Embed your app into Sugar&amp;nbsp;through &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/User_Interface/Dashlets/"&gt;Dashlets&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Simplest approach&lt;/li&gt;
&lt;li&gt;Often requires web user-based authentication&lt;/li&gt;
&lt;li&gt;All load/traffic goes directly to your system,&amp;nbsp;which makes your system the performance bottleneck&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="rest"&gt;&lt;/a&gt;REST API Webservices&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Accessing your data when you want is good. Accessing your data however you want is better. &lt;/span&gt;&lt;span&gt;When you decide to build an integration with Sugar, you&amp;rsquo;ll need an easy way to access and interact with the data stored in Sugar. The REST (&lt;/span&gt;&lt;span&gt;representational state transfer)&lt;/span&gt;&lt;span&gt;&amp;nbsp;API (application programming interface) is perfect for this.&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sugar REST API Overview
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;Fully RESTfull (GET, POST, PUT, DELETE)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;OAuth2 token based&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;All fields and modules are available through the API automatically&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Metadata API provides everything you need to know about your Sugar instance.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.33-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Topics
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/new-tutorial-intro-to-the-sugar-rest-api"&gt;Intro to the Sugar REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/how-sugar-rest-api-versioning-works"&gt;How Sugar REST API versioning works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/"&gt;RestAPI Developer Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/sugarcrm-cookbook---the-school-of-rest---part-1"&gt;School of REST blog series&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/"&gt;REST APIs Endpoints&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Extending_Endpoints/"&gt;How to add your own custom endpoints to the REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/API_Exceptions/"&gt;API Exceptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Best_Practices/"&gt;Best practices when integrating and migrating Sugar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="common"&gt;&lt;/a&gt;Common&amp;nbsp;APIs&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;It is important to understand our most commonly used APIs and their functions within Sugar. Your integration might need data within Sugar&amp;#39;s module structure that could potentially change over time, so you can use Metadata for it as well as CRUD onto Sugar.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.48-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Metadata
&lt;ul&gt;
&lt;li&gt;Endpoint with current system&amp;#39;s structure&lt;/li&gt;
&lt;li&gt;Modules, fields, relationships, layouts&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Use carefully, its payload can be MBs in size, cache as much as possible&lt;/li&gt;
&lt;li&gt;GET /metadata (use filters as much as possible)&lt;/li&gt;
&lt;li&gt;It does not retrieve labels for dropdowns, use language API to do so&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/3-tips-for-using-the-sugar-metadata-api"&gt;3 Tips for using the Sugar Metadata API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Language
&lt;ul&gt;
&lt;li&gt;Endpoint to retrieve labels&lt;/li&gt;
&lt;li&gt;Dropdown list values&lt;/li&gt;
&lt;li&gt;Any language-specific content&lt;/li&gt;
&lt;li&gt;GET /lang/&amp;lt;language_code&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CRUD (Create, Read, Update, Delete) records
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulerecord_GET"&gt;Read&lt;/a&gt;: &lt;code&gt;GET /&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/module_POST"&gt;Create&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulerecord_PUT"&gt;Update&lt;/a&gt;: &lt;code&gt;PUT&amp;nbsp;&lt;span&gt;/&amp;lt;module&amp;gt;/:record&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulerecord_DELETE"&gt;Delete&lt;/a&gt;: &lt;code&gt;DELETE&amp;nbsp;/&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulefilter_POST"&gt;Filter&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;/filter&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;You can use &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulefilter_GET"&gt;GET&lt;/a&gt; as well&lt;/li&gt;
&lt;li&gt;POST solves the issue when a query is too long and hits HTTP limits&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulerecordlinklink_name_GET"&gt;Retrieve records related to another module&lt;/a&gt;:&amp;nbsp;&lt;code&gt;GET /&amp;lt;module&amp;gt;/:record/link/:link_name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulerecordlinklink_nameremote_id_POST"&gt;Creates a relationship to a pre-existing record:&lt;/a&gt;&lt;code&gt; POST /&amp;lt;module&amp;gt;/:record/link/:link_name/:remote_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="performance"&gt;&lt;/a&gt;Performance and Best Practices&lt;/h1&gt;
&lt;div class="row"&gt;
&lt;div class="col-xs-12 col-md-9"&gt;
&lt;p&gt;As you deep dive into Sugar APIs,&amp;nbsp;you will see how easy it is to integrate to pull and push data from and to Sugar and your systems, however, you must consider performance so your integration doesn&amp;#39;t become a bottleneck between those systems.&lt;/p&gt;
&lt;p&gt;You should consider the following guidelines when implementing your integrations:&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/268x140/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.44.04-AM.png" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Use Sugar&amp;#39;s sync_key to link to remote IDs
&lt;ul&gt;
&lt;li&gt;Sugar provides in every module a sync_key field&lt;/li&gt;
&lt;li&gt;sync_key is a unique identifier for that module that links back to your external system&amp;#39;s generated key&lt;/li&gt;
&lt;li&gt;For example, account ID from ERP is AC0001, set sync_key (pass as a parameter in the POST) and sugar will create a record in account with sync_key=AC0001&lt;/li&gt;
&lt;li&gt;Next patch/update, sugar will check &amp;quot;where sync_key=&amp;#39;AC0001&amp;#39;&amp;quot; and update it (it is indexed)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Integrate Upsert APIs
&lt;ul&gt;
&lt;li&gt;Sugar&amp;#39;s &amp;quot;update or insert&amp;quot; API based on sync_key&lt;/li&gt;
&lt;li&gt;Simplifies a common operation - if record exists, update it, otherwise create it (GET followed by a&amp;nbsp;PUT or POST)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_PATCH"&gt;Upsert by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_GET"&gt;Get by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_DELETE"&gt;Delete by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulerecord_idsync_key_field_namesync_key_field_value_PATCH"&gt;Set a sync on existing record (without sync_key)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_POST"&gt;Create relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_DELETE"&gt;Delete relationship based on sync_key&lt;/a&gt;&lt;br /&gt;
&lt;ul&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Bulk API
&lt;ul&gt;
&lt;li&gt;An endpoint that encapsulates multiple API calls into one single HTTP request&lt;/li&gt;
&lt;li&gt;Requests are executed synchronously (one after the other)&lt;/li&gt;
&lt;li&gt;Reducing network latency between calls&lt;/li&gt;
&lt;li&gt;Combined with Upsert provides the best performance&lt;/li&gt;
&lt;li&gt;Careful not to add too many requests to it&lt;/li&gt;
&lt;li&gt;Start small (5 to 10 requests) and increase until you reach its max capacity&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Polling and filtering time-based with Filter API
&lt;ul&gt;
&lt;li&gt;Integration gateway (or your external system) asks Sugar every X minutes&lt;/li&gt;
&lt;li&gt;Request Filter API using &lt;code&gt;max_num&lt;/code&gt; (max number of records), offset and fields&lt;/li&gt;
&lt;li&gt;The response will provide the data as well as &lt;code&gt;next_offset&lt;/code&gt; (offset can be seen as pagination)&lt;/li&gt;
&lt;li&gt;if &lt;code&gt;next_offset&lt;/code&gt; is -1, no more records to go through&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Initial Data Load into Sugar&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Use Bulk + Upsert to achieve data loads&lt;/li&gt;
&lt;li&gt;Millions&amp;nbsp;of records may take a little while to process, plan ahead (over the weekend)&lt;/li&gt;
&lt;li&gt;Use multi-thread processes to load (for example 20 threads sending 20 bulk upsert requests)&lt;/li&gt;
&lt;li&gt;Careful with&amp;nbsp;&lt;a href="https://support.sugarcrm.com/Resources/Sugar_Cloud_Policy_Guide/#Rate_Limits"&gt;Sugar Cloud rate limits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;It&amp;#39;s always a good idea to let Sugar Support know you&amp;#39;re data loading, they will be considerate.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Understanding PHP limitations&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;PHP is single-threaded with limited resources to process your request&lt;/li&gt;
&lt;li&gt;If you send too much data using bulk, you may run out of memory for that request&lt;/li&gt;
&lt;li&gt;Push to the limits but give some room for PHP to finish the request gracefully&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Pagination for millions of records by using OFFSET will degrade performance
&lt;ul&gt;
&lt;li&gt;We rely on DB to find, sort and limit records&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/swlh/sql-pagination-you-are-probably-doing-it-wrong-d0f2719cc166"&gt;Nice article&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/a&gt;explaining how this works in details&lt;/li&gt;
&lt;li&gt;Instead of offsets, store the last processed ID and use it in the WHERE clause and sort by ID&lt;/li&gt;
&lt;li&gt;Example
&lt;ul&gt;
&lt;li&gt;Instead of: (/v11_25/Leads?max_num=1000&amp;amp;&lt;strong&gt;offset=4619000&lt;/strong&gt;&amp;amp;order_by=id)&lt;/li&gt;
&lt;li&gt;Do this&amp;nbsp;(/v11_25/Leads?&lt;strong&gt;filter=[{"id": {"$gt": &amp;rdquo;&amp;lt;last_id&amp;gt;"}}]&lt;/strong&gt;&amp;amp;max_num=1000&amp;amp;order_by=id)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If you need to add a date, make sure to add it as part of the filter and order&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3 id="mcetoc_1f5uvkqns0"&gt;&lt;span style="font-size:inherit;"&gt;You&amp;#39;re up and running, but don&amp;#39;t stop now - this is just the beginning of your journey. Now it&amp;#39;s time to &lt;a href="/dev-club/dev-onboarding/w/documentation/686/customization-for-devs"&gt;Customizations&lt;/a&gt;.&lt;/span&gt;&lt;/h3&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Integrations for Devs</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs/revision/26</link><pubDate>Thu, 22 Aug 2024 14:58:38 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:df5ca10a-d211-4e03-9873-9d48feb7b645</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs#comments</comments><description>Revision 26 posted to Dev Tutorials by Rafael Fernandes on 8/22/2024 2:58:38 PM&lt;br /&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="#approach"&gt;&lt;img alt=" " src="/resized-image/__size/269x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.42.25-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#rest"&gt;&lt;img alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.33-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#common"&gt;&lt;img alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.48-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#performance"&gt;&lt;img alt=" " src="/resized-image/__size/268x140/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.44.04-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="approach"&gt;&lt;/a&gt;Integration Approaches&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;The Sugar platform is extremely powerful, flexible, and allows for easy integration. This flexibility means that determining the&amp;nbsp;best approach for your use case scenario is the key to success.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/269x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.42.25-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Push/Pull from Sugar via REST API&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="text-decoration:underline;"&gt;Recommended&lt;/span&gt; approach&lt;/li&gt;
&lt;li&gt;Developers have full control over integration&lt;/li&gt;
&lt;li&gt;Integration can be stopped and systems will continue to work&lt;/li&gt;
&lt;li&gt;Retry mechanism: Resume integrations at any time (identify deltas through &amp;quot;last_update_time&amp;quot; flags)&lt;/li&gt;
&lt;li&gt;The time delay from/to Sugar is minimal&lt;/li&gt;
&lt;li&gt;Sugar REST API offers almost everything you need,&amp;nbsp;and can be further extended via customization&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Push to Sugar, Sugar pushes to an external queue in realtime&lt;span&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;Use Sugar Events to trigger through Logic Hooks&lt;/li&gt;
&lt;li&gt;Requires&amp;nbsp;Logic Hooks (code customization) to be created and deployed&lt;/li&gt;
&lt;li&gt;Does not offer a &amp;quot;retry mechanism&amp;quot;, if a logic hook fails to deliver to a queue or contact an external system&lt;/li&gt;
&lt;li&gt;Synchronous in nature, requires a response from an external system&lt;/li&gt;
&lt;li&gt;Needs to handle dependencies manually (contact can only be created after account)&lt;/li&gt;
&lt;li&gt;Good to have a middleware/queue in front of Sugar to receive those event triggers to&amp;nbsp;reliably&amp;nbsp;manage peak loads&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Realtime: Embed your app into Sugar&amp;nbsp;through &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/User_Interface/Dashlets/"&gt;Dashlets&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Simplest approach&lt;/li&gt;
&lt;li&gt;Often requires web user-based authentication&lt;/li&gt;
&lt;li&gt;All load/traffic goes directly to your system,&amp;nbsp;which makes your system the performance bottleneck&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="rest"&gt;&lt;/a&gt;REST API Webservices&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Accessing your data when you want is good. Accessing your data however you want is better. &lt;/span&gt;&lt;span&gt;When you decide to build an integration with Sugar, you&amp;rsquo;ll need an easy way to access and interact with the data stored in Sugar. The REST (&lt;/span&gt;&lt;span&gt;representational state transfer)&lt;/span&gt;&lt;span&gt;&amp;nbsp;API (application programming interface) is perfect for this.&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sugar REST API Overview
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;Fully RESTfull (GET, POST, PUT, DELETE)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;OAuth2 token based&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;All fields and modules are available through the API automatically&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Metadata API provides everything you need to know about your Sugar instance.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.33-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Topics
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/new-tutorial-intro-to-the-sugar-rest-api"&gt;Intro to the Sugar REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/how-sugar-rest-api-versioning-works"&gt;How Sugar REST API versioning works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/"&gt;RestAPI Developer Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/sugarcrm-cookbook---the-school-of-rest---part-1"&gt;School of REST blog series&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/"&gt;REST APIs Endpoints&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Extending_Endpoints/"&gt;How to add your own custom endpoints to the REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/API_Exceptions/"&gt;API Exceptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Best_Practices/"&gt;Best practices when integrating and migrating Sugar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="common"&gt;&lt;/a&gt;Common&amp;nbsp;APIs&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;It is important to understand our most commonly used APIs and their functions within Sugar. Your integration might need data within Sugar&amp;#39;s module structure that could potentially change over time, so you can use Metadata for it as well as CRUD onto Sugar.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.48-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Metadata
&lt;ul&gt;
&lt;li&gt;Endpoint with current system&amp;#39;s structure&lt;/li&gt;
&lt;li&gt;Modules, fields, relationships, layouts&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Use carefully, its payload can be MBs in size, cache as much as possible&lt;/li&gt;
&lt;li&gt;GET /metadata (use filters as much as possible)&lt;/li&gt;
&lt;li&gt;It does not retrieve labels for dropdowns, use language API to do so&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/3-tips-for-using-the-sugar-metadata-api"&gt;3 Tips for using the Sugar Metadata API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Language
&lt;ul&gt;
&lt;li&gt;Endpoint to retrieve labels&lt;/li&gt;
&lt;li&gt;Dropdown list values&lt;/li&gt;
&lt;li&gt;Any language-specific content&lt;/li&gt;
&lt;li&gt;GET /lang/&amp;lt;language_code&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CRUD (Create, Read, Update, Delete) records
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulerecord_GET"&gt;Read&lt;/a&gt;: &lt;code&gt;GET /&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/module_POST"&gt;Create&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulerecord_PUT"&gt;Update&lt;/a&gt;: &lt;code&gt;PUT&amp;nbsp;&lt;span&gt;/&amp;lt;module&amp;gt;/:record&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulerecord_DELETE"&gt;Delete&lt;/a&gt;: &lt;code&gt;DELETE&amp;nbsp;/&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulefilter_POST"&gt;Filter&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;/filter&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;You can use &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulefilter_GET"&gt;GET&lt;/a&gt; as well&lt;/li&gt;
&lt;li&gt;POST solves the issue when a query is too long and hits HTTP limits&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulerecordlinklink_name_GET"&gt;Retrieve records related to another module&lt;/a&gt;:&amp;nbsp;&lt;code&gt;GET /&amp;lt;module&amp;gt;/:record/link/:link_name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulerecordlinklink_nameremote_id_POST"&gt;Creates a relationship to a pre-existing record:&lt;/a&gt;&lt;code&gt; POST /&amp;lt;module&amp;gt;/:record/link/:link_name/:remote_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="performance"&gt;&lt;/a&gt;Performance and Best Practices&lt;/h1&gt;
&lt;div class="row"&gt;
&lt;div class="col-xs-12 col-md-9"&gt;
&lt;p&gt;As you deep dive into Sugar APIs,&amp;nbsp;you will see how easy it is to integrate to pull and push data from and to Sugar and your systems, however, you must consider performance so your integration doesn&amp;#39;t become a bottleneck between those systems.&lt;/p&gt;
&lt;p&gt;You should consider the following guidelines when implementing your integrations:&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/268x140/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.44.04-AM.png" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Use Sugar&amp;#39;s sync_key to link to remote IDs
&lt;ul&gt;
&lt;li&gt;Sugar provides in every module a sync_key field&lt;/li&gt;
&lt;li&gt;sync_key is a unique identifier for that module that links back to your external system&amp;#39;s generated key&lt;/li&gt;
&lt;li&gt;For example, account ID from ERP is AC0001, set sync_key (pass as a parameter in the POST) and sugar will create a record in account with sync_key=AC0001&lt;/li&gt;
&lt;li&gt;Next patch/update, sugar will check &amp;quot;where sync_key=&amp;#39;AC0001&amp;#39;&amp;quot; and update it (it is indexed)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Integrate Upsert APIs
&lt;ul&gt;
&lt;li&gt;Sugar&amp;#39;s &amp;quot;update or insert&amp;quot; API based on sync_key&lt;/li&gt;
&lt;li&gt;Simplifies a common operation - if record exists, update it, otherwise create it (GET followed by a&amp;nbsp;PUT or POST)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_PATCH"&gt;Upsert by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_GET"&gt;Get by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_DELETE"&gt;Delete by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulerecord_idsync_key_field_namesync_key_field_value_PATCH"&gt;Set a sync on existing record (without sync_key)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_POST"&gt;Create relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_DELETE"&gt;Delete relationship based on sync_key&lt;/a&gt;&lt;br /&gt;
&lt;ul&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Bulk API
&lt;ul&gt;
&lt;li&gt;An endpoint that encapsulates multiple API calls into one single HTTP request&lt;/li&gt;
&lt;li&gt;Requests are executed synchronously (one after the other)&lt;/li&gt;
&lt;li&gt;Reducing network latency between calls&lt;/li&gt;
&lt;li&gt;Combined with Upsert provides the best performance&lt;/li&gt;
&lt;li&gt;Careful not to add too many requests to it&lt;/li&gt;
&lt;li&gt;Start small (5 to 10 requests) and increase until you reach its max capacity&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Polling and filtering time-based with Filter API
&lt;ul&gt;
&lt;li&gt;Integration gateway (or your external system) asks Sugar every X minutes&lt;/li&gt;
&lt;li&gt;Request Filter API using &lt;code&gt;max_num&lt;/code&gt; (max number of records), offset and fields&lt;/li&gt;
&lt;li&gt;The response will provide the data as well as &lt;code&gt;next_offset&lt;/code&gt; (offset can be seen as pagination)&lt;/li&gt;
&lt;li&gt;if &lt;code&gt;next_offset&lt;/code&gt; is -1, no more records to go through&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Initial Data Load into Sugar&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Use Bulk + Upsert to achieve data loads&lt;/li&gt;
&lt;li&gt;Millions&amp;nbsp;of records may take a little while to process, plan ahead (over the weekend)&lt;/li&gt;
&lt;li&gt;Use multi-thread processes to load (for example 20 threads sending 20 bulk upsert requests)&lt;/li&gt;
&lt;li&gt;Careful with&amp;nbsp;&lt;a href="https://support.sugarcrm.com/Resources/Sugar_Cloud_Policy_Guide/#Rate_Limits"&gt;Sugar Cloud rate limits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;It&amp;#39;s always a good idea to let Sugar Support know you&amp;#39;re data loading, they will be considerate.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Understanding PHP limitations&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;PHP is single-threaded with limited resources to process your request&lt;/li&gt;
&lt;li&gt;If you send too much data using bulk, you may run out of memory for that request&lt;/li&gt;
&lt;li&gt;Push to the limits but give some room for PHP to finish the request gracefully&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Pagination for millions of records by using OFFSET will degrade performance
&lt;ul&gt;
&lt;li&gt;We rely on DB to find, sort and limit records&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/swlh/sql-pagination-you-are-probably-doing-it-wrong-d0f2719cc166"&gt;Nice article&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/a&gt;explaining how this works in details&lt;/li&gt;
&lt;li&gt;Instead of offsets, store the last processed ID and use it in the WHERE clause and sort by ID&lt;/li&gt;
&lt;li&gt;Example
&lt;ul&gt;
&lt;li&gt;Instead of: (/v11_25/Leads?max_num=1000&amp;amp;&lt;strong&gt;offset=4619000&lt;/strong&gt;&amp;amp;order_by=id)&lt;/li&gt;
&lt;li&gt;Do this&amp;nbsp;(/v11_25/Leads?&lt;strong&gt;filter=[{"id":&amp;rdquo;&amp;lt;last_id&amp;gt;"}]&lt;/strong&gt;&amp;amp;max_num=1000&amp;amp;order_by=id)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If you need to add a date, make sure to add it as part of the filter and order&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3 id="mcetoc_1f5uvkqns0"&gt;&lt;span style="font-size:inherit;"&gt;You&amp;#39;re up and running, but don&amp;#39;t stop now - this is just the beginning of your journey. Now it&amp;#39;s time to &lt;a href="/dev-club/dev-onboarding/w/documentation/686/customization-for-devs"&gt;Customizations&lt;/a&gt;.&lt;/span&gt;&lt;/h3&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Integrations for Devs</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs/revision/25</link><pubDate>Thu, 22 Aug 2024 14:46:54 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:df5ca10a-d211-4e03-9873-9d48feb7b645</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs#comments</comments><description>Revision 25 posted to Dev Tutorials by Rafael Fernandes on 8/22/2024 2:46:54 PM&lt;br /&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="#approach"&gt;&lt;img alt=" " src="/resized-image/__size/269x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.42.25-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#rest"&gt;&lt;img alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.33-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#common"&gt;&lt;img alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.48-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#performance"&gt;&lt;img alt=" " src="/resized-image/__size/268x140/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.44.04-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="approach"&gt;&lt;/a&gt;Integration Approaches&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;The Sugar platform is extremely powerful, flexible, and allows for easy integration. This flexibility means that determining the&amp;nbsp;best approach for your use case scenario is the key to success.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/269x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.42.25-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Push/Pull from Sugar via REST API&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="text-decoration:underline;"&gt;Recommended&lt;/span&gt; approach&lt;/li&gt;
&lt;li&gt;Developers have full control over integration&lt;/li&gt;
&lt;li&gt;Integration can be stopped and systems will continue to work&lt;/li&gt;
&lt;li&gt;Retry mechanism: Resume integrations at any time (identify deltas through &amp;quot;last_update_time&amp;quot; flags)&lt;/li&gt;
&lt;li&gt;The time delay from/to Sugar is minimal&lt;/li&gt;
&lt;li&gt;Sugar REST API offers almost everything you need,&amp;nbsp;and can be further extended via customization&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Push to Sugar, Sugar pushes to an external queue in realtime&lt;span&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;Use Sugar Events to trigger through Logic Hooks&lt;/li&gt;
&lt;li&gt;Requires&amp;nbsp;Logic Hooks (code customization) to be created and deployed&lt;/li&gt;
&lt;li&gt;Does not offer a &amp;quot;retry mechanism&amp;quot;, if a logic hook fails to deliver to a queue or contact an external system&lt;/li&gt;
&lt;li&gt;Synchronous in nature, requires a response from an external system&lt;/li&gt;
&lt;li&gt;Needs to handle dependencies manually (contact can only be created after account)&lt;/li&gt;
&lt;li&gt;Good to have a middleware/queue in front of Sugar to receive those event triggers to&amp;nbsp;reliably&amp;nbsp;manage peak loads&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Realtime: Embed your app into Sugar&amp;nbsp;through &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/User_Interface/Dashlets/"&gt;Dashlets&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Simplest approach&lt;/li&gt;
&lt;li&gt;Often requires web user-based authentication&lt;/li&gt;
&lt;li&gt;All load/traffic goes directly to your system,&amp;nbsp;which makes your system the performance bottleneck&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="rest"&gt;&lt;/a&gt;REST API Webservices&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Accessing your data when you want is good. Accessing your data however you want is better. &lt;/span&gt;&lt;span&gt;When you decide to build an integration with Sugar, you&amp;rsquo;ll need an easy way to access and interact with the data stored in Sugar. The REST (&lt;/span&gt;&lt;span&gt;representational state transfer)&lt;/span&gt;&lt;span&gt;&amp;nbsp;API (application programming interface) is perfect for this.&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sugar REST API Overview
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;Fully RESTfull (GET, POST, PUT, DELETE)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;OAuth2 token based&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;All fields and modules are available through the API automatically&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Metadata API provides everything you need to know about your Sugar instance.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.33-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Topics
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/new-tutorial-intro-to-the-sugar-rest-api"&gt;Intro to the Sugar REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/how-sugar-rest-api-versioning-works"&gt;How Sugar REST API versioning works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/"&gt;RestAPI Developer Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/sugarcrm-cookbook---the-school-of-rest---part-1"&gt;School of REST blog series&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/"&gt;REST APIs Endpoints&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Extending_Endpoints/"&gt;How to add your own custom endpoints to the REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/API_Exceptions/"&gt;API Exceptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Best_Practices/"&gt;Best practices when integrating and migrating Sugar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="common"&gt;&lt;/a&gt;Common&amp;nbsp;APIs&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;It is important to understand our most commonly used APIs and their functions within Sugar. Your integration might need data within Sugar&amp;#39;s module structure that could potentially change over time, so you can use Metadata for it as well as CRUD onto Sugar.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.48-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Metadata
&lt;ul&gt;
&lt;li&gt;Endpoint with current system&amp;#39;s structure&lt;/li&gt;
&lt;li&gt;Modules, fields, relationships, layouts&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Use carefully, its payload can be MBs in size, cache as much as possible&lt;/li&gt;
&lt;li&gt;GET /metadata (use filters as much as possible)&lt;/li&gt;
&lt;li&gt;It does not retrieve labels for dropdowns, use language API to do so&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/3-tips-for-using-the-sugar-metadata-api"&gt;3 Tips for using the Sugar Metadata API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Language
&lt;ul&gt;
&lt;li&gt;Endpoint to retrieve labels&lt;/li&gt;
&lt;li&gt;Dropdown list values&lt;/li&gt;
&lt;li&gt;Any language-specific content&lt;/li&gt;
&lt;li&gt;GET /lang/&amp;lt;language_code&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CRUD (Create, Read, Update, Delete) records
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulerecord_GET"&gt;Read&lt;/a&gt;: &lt;code&gt;GET /&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/module_POST"&gt;Create&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulerecord_PUT"&gt;Update&lt;/a&gt;: &lt;code&gt;PUT&amp;nbsp;&lt;span&gt;/&amp;lt;module&amp;gt;/:record&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulerecord_DELETE"&gt;Delete&lt;/a&gt;: &lt;code&gt;DELETE&amp;nbsp;/&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulefilter_POST"&gt;Filter&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;/filter&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;You can use &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulefilter_GET"&gt;GET&lt;/a&gt; as well&lt;/li&gt;
&lt;li&gt;POST solves the issue when a query is too long and hits HTTP limits&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulerecordlinklink_name_GET"&gt;Retrieve records related to another module&lt;/a&gt;:&amp;nbsp;&lt;code&gt;GET /&amp;lt;module&amp;gt;/:record/link/:link_name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/rest_api/Endpoints/modulerecordlinklink_nameremote_id_POST"&gt;Creates a relationship to a pre-existing record:&lt;/a&gt;&lt;code&gt; POST /&amp;lt;module&amp;gt;/:record/link/:link_name/:remote_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="performance"&gt;&lt;/a&gt;Performance and Best Practices&lt;/h1&gt;
&lt;div class="row"&gt;
&lt;div class="col-xs-12 col-md-9"&gt;
&lt;p&gt;As you deep dive into Sugar APIs,&amp;nbsp;you will see how easy it is to integrate to pull and push data from and to Sugar and your systems, however, you must consider performance so your integration doesn&amp;#39;t become a bottleneck between those systems.&lt;/p&gt;
&lt;p&gt;You should consider the following guidelines when implementing your integrations:&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/268x140/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.44.04-AM.png" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Use Sugar&amp;#39;s sync_key to link to remote IDs
&lt;ul&gt;
&lt;li&gt;Sugar provides in every module a sync_key field&lt;/li&gt;
&lt;li&gt;sync_key is a unique identifier for that module that links back to your external system&amp;#39;s generated key&lt;/li&gt;
&lt;li&gt;For example, account ID from ERP is AC0001, set sync_key (pass as a parameter in the POST) and sugar will create a record in account with sync_key=AC0001&lt;/li&gt;
&lt;li&gt;Next patch/update, sugar will check &amp;quot;where sync_key=&amp;#39;AC0001&amp;#39;&amp;quot; and update it (it is indexed)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Integrate Upsert APIs
&lt;ul&gt;
&lt;li&gt;Sugar&amp;#39;s &amp;quot;update or insert&amp;quot; API based on sync_key&lt;/li&gt;
&lt;li&gt;Simplifies a common operation - if record exists, update it, otherwise create it (GET followed by a&amp;nbsp;PUT or POST)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_PATCH"&gt;Upsert by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_GET"&gt;Get by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_DELETE"&gt;Delete by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulerecord_idsync_key_field_namesync_key_field_value_PATCH"&gt;Set a sync on existing record (without sync_key)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_POST"&gt;Create relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_DELETE"&gt;Delete relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Bulk API
&lt;ul&gt;
&lt;li&gt;An endpoint that encapsulates multiple API calls into one single HTTP request&lt;/li&gt;
&lt;li&gt;Requests are executed synchronously (one after the other)&lt;/li&gt;
&lt;li&gt;Reducing network latency between calls&lt;/li&gt;
&lt;li&gt;Combined with Upsert provides the best performance&lt;/li&gt;
&lt;li&gt;Careful not to add too many requests to it&lt;/li&gt;
&lt;li&gt;Start small (5 to 10 requests) and increase until you reach its max capacity&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Polling and filtering time-based with Filter API
&lt;ul&gt;
&lt;li&gt;Integration gateway (or your external system) asks Sugar every X minutes&lt;/li&gt;
&lt;li&gt;Request Filter API using &lt;code&gt;max_num&lt;/code&gt; (max number of records), offset and fields&lt;/li&gt;
&lt;li&gt;The response will provide the data as well as &lt;code&gt;next_offset&lt;/code&gt; (offset can be seen as pagination)&lt;/li&gt;
&lt;li&gt;if &lt;code&gt;next_offset&lt;/code&gt; is -1, no more records to go through&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Initial Data Load into Sugar&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Use Bulk + Upsert to achieve data loads&lt;/li&gt;
&lt;li&gt;Millions&amp;nbsp;of records may take a little while to process, plan ahead (over the weekend)&lt;/li&gt;
&lt;li&gt;Use multi-thread processes to load (for example 20 threads sending 20 bulk upsert requests)&lt;/li&gt;
&lt;li&gt;Careful with&amp;nbsp;&lt;a href="https://support.sugarcrm.com/Resources/Sugar_Cloud_Policy_Guide/#Rate_Limits"&gt;Sugar Cloud rate limits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;It&amp;#39;s always a good idea to let Sugar Support know you&amp;#39;re data loading, they will be considerate.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Understanding PHP limitations&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;PHP is single-threaded with limited resources to process your request&lt;/li&gt;
&lt;li&gt;If you send too much data using bulk, you may run out of memory for that request&lt;/li&gt;
&lt;li&gt;Push to the limits but give some room for PHP to finish the request gracefully&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Pagination for millions of records by using OFFSET will degrade performance
&lt;ul&gt;
&lt;li&gt;We rely on DB to find, sort and limit records&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/swlh/sql-pagination-you-are-probably-doing-it-wrong-d0f2719cc166"&gt;Nice article&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/a&gt;explaining how this works in details&lt;/li&gt;
&lt;li&gt;Instead of offsets, store the last processed ID and use it in the WHERE clause and sort by ID&lt;/li&gt;
&lt;li&gt;Example
&lt;ul&gt;
&lt;li&gt;Instead of: (/v11_25/Leads?max_num=1000&amp;amp;&lt;strong&gt;offset=4619000&lt;/strong&gt;&amp;amp;order_by=id)&lt;/li&gt;
&lt;li&gt;Do this&amp;nbsp;(/v11_25/Leads?&lt;strong&gt;filter=[{"id":&amp;rdquo;&amp;lt;last_id&amp;gt;"}]&lt;/strong&gt;&amp;amp;max_num=1000&amp;amp;order_by=id)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If you need to add a date, make sure to add it as part of the filter and order&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3 id="mcetoc_1f5uvkqns0"&gt;&lt;span style="font-size:inherit;"&gt;You&amp;#39;re up and running, but don&amp;#39;t stop now - this is just the beginning of your journey. Now it&amp;#39;s time to &lt;a href="/dev-club/dev-onboarding/w/documentation/686/customization-for-devs"&gt;Customizations&lt;/a&gt;.&lt;/span&gt;&lt;/h3&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Integrations for Devs</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs/revision/24</link><pubDate>Mon, 24 Jun 2024 12:33:52 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:df5ca10a-d211-4e03-9873-9d48feb7b645</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs#comments</comments><description>Revision 24 posted to Dev Tutorials by Rafael Fernandes on 6/24/2024 12:33:52 PM&lt;br /&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="#approach"&gt;&lt;img alt=" " src="/resized-image/__size/269x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.42.25-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#rest"&gt;&lt;img alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.33-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#common"&gt;&lt;img alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.48-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#performance"&gt;&lt;img alt=" " src="/resized-image/__size/268x140/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.44.04-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="approach"&gt;&lt;/a&gt;Integration Approaches&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;The Sugar platform is extremely powerful, flexible, and allows for easy integration. This flexibility means that determining the&amp;nbsp;best approach for your use case scenario is the key to success.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/269x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.42.25-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Push/Pull from Sugar via REST API&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="text-decoration:underline;"&gt;Recommended&lt;/span&gt; approach&lt;/li&gt;
&lt;li&gt;Developers have full control over integration&lt;/li&gt;
&lt;li&gt;Integration can be stopped and systems will continue to work&lt;/li&gt;
&lt;li&gt;Retry mechanism: Resume integrations at any time (identify deltas through &amp;quot;last_update_time&amp;quot; flags)&lt;/li&gt;
&lt;li&gt;The time delay from/to Sugar is minimal&lt;/li&gt;
&lt;li&gt;Sugar REST API offers almost everything you need,&amp;nbsp;and can be further extended via customization&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Push to Sugar, Sugar pushes to an external queue in realtime&lt;span&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;Use Sugar Events to trigger through Logic Hooks&lt;/li&gt;
&lt;li&gt;Requires&amp;nbsp;Logic Hooks (code customization) to be created and deployed&lt;/li&gt;
&lt;li&gt;Does not offer a &amp;quot;retry mechanism&amp;quot;, if a logic hook fails to deliver to a queue or contact an external system&lt;/li&gt;
&lt;li&gt;Synchronous in nature, requires a response from an external system&lt;/li&gt;
&lt;li&gt;Needs to handle dependencies manually (contact can only be created after account)&lt;/li&gt;
&lt;li&gt;Good to have a middleware/queue in front of Sugar to receive those event triggers to&amp;nbsp;reliably&amp;nbsp;manage peak loads&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Realtime: Embed your app into Sugar&amp;nbsp;through &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/User_Interface/Dashlets/"&gt;Dashlets&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Simplest approach&lt;/li&gt;
&lt;li&gt;Often requires web user-based authentication&lt;/li&gt;
&lt;li&gt;All load/traffic goes directly to your system,&amp;nbsp;which makes your system the performance bottleneck&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="rest"&gt;&lt;/a&gt;REST API Webservices&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Accessing your data when you want is good. Accessing your data however you want is better. &lt;/span&gt;&lt;span&gt;When you decide to build an integration with Sugar, you&amp;rsquo;ll need an easy way to access and interact with the data stored in Sugar. The REST (&lt;/span&gt;&lt;span&gt;representational state transfer)&lt;/span&gt;&lt;span&gt;&amp;nbsp;API (application programming interface) is perfect for this.&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sugar REST API Overview
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;Fully RESTfull (GET, POST, PUT, DELETE)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;OAuth2 token based&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;All fields and modules are available through the API automatically&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Metadata API provides everything you need to know about your Sugar instance.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.33-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Topics
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/new-tutorial-intro-to-the-sugar-rest-api"&gt;Intro to the Sugar REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/how-sugar-rest-api-versioning-works"&gt;How Sugar REST API versioning works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/"&gt;RestAPI Developer Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/sugarcrm-cookbook---the-school-of-rest---part-1"&gt;School of REST blog series&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/"&gt;REST APIs Endpoints&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Extending_Endpoints/"&gt;How to add your own custom endpoints to the REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/API_Exceptions/"&gt;API Exceptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Best_Practices/"&gt;Best practices when integrating and migrating Sugar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="common"&gt;&lt;/a&gt;Common&amp;nbsp;APIs&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;It is important to understand our most commonly used APIs and their functions within Sugar. Your integration might need data within Sugar&amp;#39;s module structure that could potentially change over time, so you can use Metadata for it as well as CRUD onto Sugar.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.48-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Metadata
&lt;ul&gt;
&lt;li&gt;Endpoint with current system&amp;#39;s structure&lt;/li&gt;
&lt;li&gt;Modules, fields, relationships, layouts&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Use carefully, its payload can be MBs in size, cache as much as possible&lt;/li&gt;
&lt;li&gt;GET /metadata (use filters as much as possible)&lt;/li&gt;
&lt;li&gt;It does not retrieve labels for dropdowns, use language API to do so&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/3-tips-for-using-the-sugar-metadata-api"&gt;3 Tips for using the Sugar Metadata API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Language
&lt;ul&gt;
&lt;li&gt;Endpoint to retrieve labels&lt;/li&gt;
&lt;li&gt;Dropdown list values&lt;/li&gt;
&lt;li&gt;Any language-specific content&lt;/li&gt;
&lt;li&gt;GET /lang/&amp;lt;language_code&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CRUD (Create, Read, Update, Delete) records
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_GET"&gt;Read&lt;/a&gt;: &lt;code&gt;GET /&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/module_POST"&gt;Create&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_PUT"&gt;Update&lt;/a&gt;: &lt;code&gt;PUT&amp;nbsp;&lt;span&gt;/&amp;lt;module&amp;gt;/:record&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_DELETE"&gt;Delete&lt;/a&gt;: &lt;code&gt;DELETE&amp;nbsp;/&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_POST"&gt;Filter&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;/filter&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;You can use &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_GET"&gt;GET&lt;/a&gt; as well&lt;/li&gt;
&lt;li&gt;POST solves the issue when a query is too long and hits HTTP limits&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_name_GET"&gt;Retrieve records related to another module&lt;/a&gt;:&amp;nbsp;&lt;code&gt;GET /&amp;lt;module&amp;gt;/:record/link/:link_name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_nameremote_id_POST"&gt;Creates a relationship to a pre-existing record:&lt;/a&gt;&lt;code&gt; POST /&amp;lt;module&amp;gt;/:record/link/:link_name/:remote_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="performance"&gt;&lt;/a&gt;Performance and Best Practices&lt;/h1&gt;
&lt;div class="row"&gt;
&lt;div class="col-xs-12 col-md-9"&gt;
&lt;p&gt;As you deep dive into Sugar APIs,&amp;nbsp;you will see how easy it is to integrate to pull and push data from and to Sugar and your systems, however, you must consider performance so your integration doesn&amp;#39;t become a bottleneck between those systems.&lt;/p&gt;
&lt;p&gt;You should consider the following guidelines when implementing your integrations:&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/268x140/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.44.04-AM.png" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Use Sugar&amp;#39;s sync_key to link to remote IDs
&lt;ul&gt;
&lt;li&gt;Sugar provides in every module a sync_key field&lt;/li&gt;
&lt;li&gt;sync_key is a unique identifier for that module that links back to your external system&amp;#39;s generated key&lt;/li&gt;
&lt;li&gt;For example, account ID from ERP is AC0001, set sync_key (pass as a parameter in the POST) and sugar will create a record in account with sync_key=AC0001&lt;/li&gt;
&lt;li&gt;Next patch/update, sugar will check &amp;quot;where sync_key=&amp;#39;AC0001&amp;#39;&amp;quot; and update it (it is indexed)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Integrate Upsert APIs
&lt;ul&gt;
&lt;li&gt;Sugar&amp;#39;s &amp;quot;update or insert&amp;quot; API based on sync_key&lt;/li&gt;
&lt;li&gt;Simplifies a common operation - if record exists, update it, otherwise create it (GET followed by a&amp;nbsp;PUT or POST)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_PATCH"&gt;Upsert by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_GET"&gt;Get by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_DELETE"&gt;Delete by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulerecord_idsync_key_field_namesync_key_field_value_PATCH"&gt;Set a sync on existing record (without sync_key)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_POST"&gt;Create relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_DELETE"&gt;Delete relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Bulk API
&lt;ul&gt;
&lt;li&gt;An endpoint that encapsulates multiple API calls into one single HTTP request&lt;/li&gt;
&lt;li&gt;Requests are executed synchronously (one after the other)&lt;/li&gt;
&lt;li&gt;Reducing network latency between calls&lt;/li&gt;
&lt;li&gt;Combined with Upsert provides the best performance&lt;/li&gt;
&lt;li&gt;Careful not to add too many requests to it&lt;/li&gt;
&lt;li&gt;Start small (5 to 10 requests) and increase until you reach its max capacity&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Polling and filtering time-based with Filter API
&lt;ul&gt;
&lt;li&gt;Integration gateway (or your external system) asks Sugar every X minutes&lt;/li&gt;
&lt;li&gt;Request Filter API using &lt;code&gt;max_num&lt;/code&gt; (max number of records), offset and fields&lt;/li&gt;
&lt;li&gt;The response will provide the data as well as &lt;code&gt;next_offset&lt;/code&gt; (offset can be seen as pagination)&lt;/li&gt;
&lt;li&gt;if &lt;code&gt;next_offset&lt;/code&gt; is -1, no more records to go through&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Initial Data Load into Sugar&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Use Bulk + Upsert to achieve data loads&lt;/li&gt;
&lt;li&gt;Millions&amp;nbsp;of records may take a little while to process, plan ahead (over the weekend)&lt;/li&gt;
&lt;li&gt;Use multi-thread processes to load (for example 20 threads sending 20 bulk upsert requests)&lt;/li&gt;
&lt;li&gt;Careful with&amp;nbsp;&lt;a href="https://support.sugarcrm.com/Resources/Sugar_Cloud_Policy_Guide/#Rate_Limits"&gt;Sugar Cloud rate limits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;It&amp;#39;s always a good idea to let Sugar Support know you&amp;#39;re data loading, they will be considerate.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Understanding PHP limitations&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;PHP is single-threaded with limited resources to process your request&lt;/li&gt;
&lt;li&gt;If you send too much data using bulk, you may run out of memory for that request&lt;/li&gt;
&lt;li&gt;Push to the limits but give some room for PHP to finish the request gracefully&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Pagination for millions of records by using OFFSET will degrade performance
&lt;ul&gt;
&lt;li&gt;We rely on DB to find, sort and limit records&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/swlh/sql-pagination-you-are-probably-doing-it-wrong-d0f2719cc166"&gt;Nice article&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/a&gt;explaining how this works in details&lt;/li&gt;
&lt;li&gt;Instead of offsets, store the last processed ID and use it in the WHERE clause and sort by ID&lt;/li&gt;
&lt;li&gt;Example
&lt;ul&gt;
&lt;li&gt;Instead of: (/v11_25/Leads?max_num=1000&amp;amp;&lt;strong&gt;offset=4619000&lt;/strong&gt;&amp;amp;order_by=id)&lt;/li&gt;
&lt;li&gt;Do this&amp;nbsp;(/v11_25/Leads?&lt;strong&gt;filter=[{"id":&amp;rdquo;&amp;lt;last_id&amp;gt;"}]&lt;/strong&gt;&amp;amp;max_num=1000&amp;amp;order_by=id)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If you need to add a date, make sure to add it as part of the filter and order&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3 id="mcetoc_1f5uvkqns0"&gt;&lt;span style="font-size:inherit;"&gt;You&amp;#39;re up and running, but don&amp;#39;t stop now - this is just the beginning of your journey. Now it&amp;#39;s time to &lt;a href="/dev-club/dev-onboarding/w/documentation/686/customization-for-devs"&gt;Customizations&lt;/a&gt;.&lt;/span&gt;&lt;/h3&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Integrations for Devs</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs/revision/23</link><pubDate>Fri, 05 Aug 2022 17:45:09 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:df5ca10a-d211-4e03-9873-9d48feb7b645</guid><dc:creator>Alex Nassi</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs#comments</comments><description>Revision 23 posted to Dev Tutorials by Alex Nassi on 8/5/2022 5:45:09 PM&lt;br /&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="#approach"&gt;&lt;img alt=" " src="/resized-image/__size/269x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.42.25-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#rest"&gt;&lt;img alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.33-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#common"&gt;&lt;img alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.48-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#performance"&gt;&lt;img alt=" " src="/resized-image/__size/268x140/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.44.04-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="approach"&gt;&lt;/a&gt;Integration Approaches&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;The Sugar platform is extremely powerful, flexible, and allows for easy integration. This flexibility means that determining the&amp;nbsp;best approach for your use case scenario is the key to success.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/269x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.42.25-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Push/Pull from Sugar via REST API&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="text-decoration:underline;"&gt;Recommended&lt;/span&gt; approach&lt;/li&gt;
&lt;li&gt;Developers have full control over integration&lt;/li&gt;
&lt;li&gt;Integration can be stopped and systems will continue to work&lt;/li&gt;
&lt;li&gt;Retry mechanism: Resume integrations at any time (identify deltas through &amp;quot;last_update_time&amp;quot; flags)&lt;/li&gt;
&lt;li&gt;The time delay from/to Sugar is minimal&lt;/li&gt;
&lt;li&gt;Sugar REST API offers almost everything you need,&amp;nbsp;and can be further extended via customization&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Push to Sugar, Sugar pushes to an external queue in realtime&lt;span&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;Use Sugar Events to trigger through Logic Hooks&lt;/li&gt;
&lt;li&gt;Requires&amp;nbsp;Logic Hooks (code customization) to be created and deployed&lt;/li&gt;
&lt;li&gt;Does not offer a &amp;quot;retry mechanism&amp;quot;, if a logic hook fails to deliver to a queue or contact an external system&lt;/li&gt;
&lt;li&gt;Synchronous in nature, requires a response from an external system&lt;/li&gt;
&lt;li&gt;Needs to handle dependencies manually (contact can only be created after account)&lt;/li&gt;
&lt;li&gt;Good to have a middleware/queue in front of Sugar to receive those event triggers to&amp;nbsp;reliably&amp;nbsp;manage peak loads&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Realtime: Embed your app into Sugar&amp;nbsp;through &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/User_Interface/Dashlets/"&gt;Dashlets&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Simplest approach&lt;/li&gt;
&lt;li&gt;Often requires web user-based authentication&lt;/li&gt;
&lt;li&gt;All load/traffic goes directly to your system,&amp;nbsp;which makes your system the performance bottleneck&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="rest"&gt;&lt;/a&gt;REST API Webservices&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Accessing your data when you want is good. Accessing your data however you want is better. &lt;/span&gt;&lt;span&gt;When you decide to build an integration with Sugar, you&amp;rsquo;ll need an easy way to access and interact with the data stored in Sugar. The REST (&lt;/span&gt;&lt;span&gt;representational state transfer)&lt;/span&gt;&lt;span&gt;&amp;nbsp;API (application programming interface) is perfect for this.&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sugar REST API Overview
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;Fully RESTfull (GET, POST, PUT, DELETE)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;OAuth2 token based&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;All fields and modules are available through the API automatically&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Metadata API provides everything you need to know about your Sugar instance.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.33-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Topics
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/new-tutorial-intro-to-the-sugar-rest-api"&gt;Intro to the Sugar REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/how-sugar-rest-api-versioning-works"&gt;How Sugar REST API versioning works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/"&gt;RestAPI Developer Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/sugarcrm-cookbook---the-school-of-rest---part-1"&gt;School of REST blog series&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/"&gt;REST APIs Endpoints&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Extending_Endpoints/"&gt;How to add your own custom endpoints to the REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/API_Exceptions/"&gt;API Exceptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Best_Practices/"&gt;Best practices when integrating and migrating Sugar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="common"&gt;&lt;/a&gt;Common&amp;nbsp;APIs&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;It is important to understand our most commonly used APIs and their functions within Sugar. Your integration might need data within Sugar&amp;#39;s module structure that could potentially change over time, so you can use Metadata for it as well as CRUD onto Sugar.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.48-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Metadata
&lt;ul&gt;
&lt;li&gt;Endpoint with current system&amp;#39;s structure&lt;/li&gt;
&lt;li&gt;Modules, fields, relationships, layouts&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Use carefully, its payload can be MBs in size, cache as much as possible&lt;/li&gt;
&lt;li&gt;GET /metadata (use filters as much as possible)&lt;/li&gt;
&lt;li&gt;It does not retrieve labels for dropdowns, use language API to do so&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/3-tips-for-using-the-sugar-metadata-api"&gt;3 Tips for using the Sugar Metadata API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Language
&lt;ul&gt;
&lt;li&gt;Endpoint to retrieve labels&lt;/li&gt;
&lt;li&gt;Dropdown list values&lt;/li&gt;
&lt;li&gt;Any language-specific content&lt;/li&gt;
&lt;li&gt;GET /lang/&amp;lt;language_code&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CRUD (Create, Read, Update, Delete) records
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_GET"&gt;Read&lt;/a&gt;: &lt;code&gt;GET /&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/module_POST"&gt;Create&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_PUT"&gt;Update&lt;/a&gt;: &lt;code&gt;PUT&amp;nbsp;&lt;span&gt;/&amp;lt;module&amp;gt;/:record&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_DELETE"&gt;Delete&lt;/a&gt;: &lt;code&gt;DELETE&amp;nbsp;/&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_POST"&gt;Filter&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;/filter&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;You can use &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_GET"&gt;GET&lt;/a&gt; as well&lt;/li&gt;
&lt;li&gt;POST solves the issue when a query is too long and hits HTTP limits&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_name_GET"&gt;Retrieve records related to another module&lt;/a&gt;:&amp;nbsp;&lt;code&gt;GET /&amp;lt;module&amp;gt;/:record/link/:link_name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_nameremote_id_POST"&gt;Creates a relationship to a pre-existing record:&lt;/a&gt;&lt;code&gt; POST /&amp;lt;module&amp;gt;/:record/link/:link_name/:remote_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="performance"&gt;&lt;/a&gt;Performance and Best Practices&lt;/h1&gt;
&lt;div class="row"&gt;
&lt;div class="col-xs-12 col-md-9"&gt;
&lt;p&gt;As you deep dive into Sugar APIs,&amp;nbsp;you will see how easy it is to integrate to pull and push data from and to Sugar and your systems, however, you must consider performance so your integration doesn&amp;#39;t become a bottleneck between those systems.&lt;/p&gt;
&lt;p&gt;You should consider the following guidelines when implementing your integrations:&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/268x140/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.44.04-AM.png" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Use Sugar&amp;#39;s sync_key to link to remote IDs
&lt;ul&gt;
&lt;li&gt;Sugar provides in every module a sync_key field&lt;/li&gt;
&lt;li&gt;sync_key is a unique identifier for that module that links back to your external system&amp;#39;s generated key&lt;/li&gt;
&lt;li&gt;For example, account ID from ERP is AC0001, set sync_key (pass as a parameter in the POST) and sugar will create a record in account with sync_key=AC0001&lt;/li&gt;
&lt;li&gt;Next patch/update, sugar will check &amp;quot;where sync_key=&amp;#39;AC0001&amp;#39;&amp;quot; and update it (it is indexed)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Integrate Upsert APIs
&lt;ul&gt;
&lt;li&gt;Sugar&amp;#39;s &amp;quot;update or insert&amp;quot; API based on sync_key&lt;/li&gt;
&lt;li&gt;Simplifies a common operation - if record exists, update it, otherwise create it (GET followed by a&amp;nbsp;PUT or POST)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_PATCH"&gt;Upsert by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_GET"&gt;Get by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_DELETE"&gt;Delete by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulerecord_idsync_key_field_namesync_key_field_value_PATCH"&gt;Set a sync on existing record (without sync_key)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_POST"&gt;Create relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_DELETE"&gt;Delete relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Bulk API
&lt;ul&gt;
&lt;li&gt;An endpoint that encapsulates multiple API calls into one single HTTP request&lt;/li&gt;
&lt;li&gt;Requests are executed synchronously (one after the other)&lt;/li&gt;
&lt;li&gt;Reducing network latency between calls&lt;/li&gt;
&lt;li&gt;Combined with Upsert provides the best performance&lt;/li&gt;
&lt;li&gt;Careful not to add too many requests to it&lt;/li&gt;
&lt;li&gt;Start small (5 to 10 requests) and increase until you reach its max capacity&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Polling and filtering time-based with Filter API
&lt;ul&gt;
&lt;li&gt;Integration gateway (or your external system) asks Sugar every X minutes&lt;/li&gt;
&lt;li&gt;Request Filter API using &lt;code&gt;max_num&lt;/code&gt; (max number of records), offset and fields&lt;/li&gt;
&lt;li&gt;The response will provide the data as well as &lt;code&gt;next_offset&lt;/code&gt; (offset can be seen as pagination)&lt;/li&gt;
&lt;li&gt;if &lt;code&gt;next_offset&lt;/code&gt; is -1, no more records to go through&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Initial Data Load into Sugar&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Use Bulk + Upsert to achieve data loads&lt;/li&gt;
&lt;li&gt;Millions&amp;nbsp;of records may take a little while to process, plan ahead (over the weekend)&lt;/li&gt;
&lt;li&gt;Use multi-thread processes to load (for example 20 threads sending 20 bulk upsert requests)&lt;/li&gt;
&lt;li&gt;Careful with&amp;nbsp;&lt;a href="https://support.sugarcrm.com/Resources/Sugar_Cloud_Policy_Guide/#Rate_Limits"&gt;Sugar Cloud rate limits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;It&amp;#39;s always a good idea to let Sugar Support know you&amp;#39;re data loading, they will be considerate.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Understanding PHP limitations&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;PHP is single-threaded with limited resources to process your request&lt;/li&gt;
&lt;li&gt;If you send too much data using bulk, you may run out of memory for that request&lt;/li&gt;
&lt;li&gt;Push to the limits but give some room for PHP to finish the request gracefully&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3 id="mcetoc_1f5uvkqns0"&gt;&lt;span style="font-size:inherit;"&gt;You&amp;#39;re up and running, but don&amp;#39;t stop now - this is just the beginning of your journey. Now it&amp;#39;s time to &lt;a href="/dev-club/dev-onboarding/w/documentation/686/customization-for-devs"&gt;Customizations&lt;/a&gt;.&lt;/span&gt;&lt;/h3&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Integrations for Devs</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs/revision/21</link><pubDate>Thu, 21 Jul 2022 18:49:00 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:df5ca10a-d211-4e03-9873-9d48feb7b645</guid><dc:creator>Matt Marum</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs#comments</comments><description>Revision 21 posted to Dev Tutorials by Matt Marum on 7/21/2022 6:49:00 PM&lt;br /&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="#approach"&gt;&lt;img alt=" " src="/resized-image/__size/269x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.42.25-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#rest"&gt;&lt;img alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.33-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#common"&gt;&lt;img alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.48-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#performance"&gt;&lt;img alt=" " src="/resized-image/__size/268x140/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.44.04-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="approach"&gt;&lt;/a&gt;Integration Approaches&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;The Sugar platform is extremely powerful, flexible, and allows for easy integration. This flexibility means that determining the&amp;nbsp;best approach for your use case scenario is the key to success.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/269x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.42.25-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Push/Pull from Sugar via REST API&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="text-decoration:underline;"&gt;Recommended&lt;/span&gt; approach&lt;/li&gt;
&lt;li&gt;Developers have full control over integration&lt;/li&gt;
&lt;li&gt;Integration can be stopped and systems will continue to work&lt;/li&gt;
&lt;li&gt;Retry mechanism: Resume integrations at any time (identify deltas through &amp;quot;last_update_time&amp;quot; flags)&lt;/li&gt;
&lt;li&gt;The time delay from/to Sugar is minimal&lt;/li&gt;
&lt;li&gt;Sugar REST API offers almost everything you need,&amp;nbsp;and can be further extended via customization&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Push to Sugar, Sugar pushes to an external queue in realtime&lt;span&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;Use Sugar Events to trigger through Logic Hooks&lt;/li&gt;
&lt;li&gt;Requires&amp;nbsp;Logic Hooks (code customization) to be created and deployed&lt;/li&gt;
&lt;li&gt;Does not offer a &amp;quot;retry mechanism&amp;quot;, if a logic hook fails to deliver to a queue or contact an external system&lt;/li&gt;
&lt;li&gt;Synchronous in nature, requires a response from an external system&lt;/li&gt;
&lt;li&gt;Needs to handle dependencies manually (contact can only be created after account)&lt;/li&gt;
&lt;li&gt;Good to have a middleware/queue in front of Sugar to receive those event triggers to&amp;nbsp;reliably&amp;nbsp;manage peak loads&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Realtime: Embed your app into Sugar&amp;nbsp;through &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/User_Interface/Dashlets/"&gt;Dashlets&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Simplest approach&lt;/li&gt;
&lt;li&gt;Often requires web user-based authentication&lt;/li&gt;
&lt;li&gt;All load/traffic goes directly to your system,&amp;nbsp;which makes your system the performance bottleneck&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="rest"&gt;&lt;/a&gt;REST API Webservices&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Accessing your data when you want is good. Accessing your data however you want is better. &lt;/span&gt;&lt;span&gt;When you decide to build an integration with Sugar, you&amp;rsquo;ll need an easy way to access and interact with the data stored in Sugar. The REST (&lt;/span&gt;&lt;span&gt;representational state transfer)&lt;/span&gt;&lt;span&gt;&amp;nbsp;API (application programming interface) is perfect for this.&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sugar REST API Overview
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;Fully RESTfull (GET, POST, PUT, DELETE)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;OAuth2 token based&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;All fields and modules are available through the API automatically&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Metadata API provides everything you need to know about your Sugar instance.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.33-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Topics
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/new-tutorial-intro-to-the-sugar-rest-api"&gt;Intro to the Sugar REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/how-sugar-rest-api-versioning-works"&gt;How Sugar REST API versioning works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/"&gt;RestAPI Developer Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/sugarcrm-cookbook---the-school-of-rest---part-1"&gt;School of REST blog series&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/"&gt;REST APIs Endpoints&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Extending_Endpoints/"&gt;How to add your own custom endpoints to the REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/API_Exceptions/"&gt;API Exceptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Best_Practices/"&gt;Best practices when integrating and migrating Sugar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="common"&gt;&lt;/a&gt;Common&amp;nbsp;APIs&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;It is important to understand our most commonly used APIs and their functions within Sugar. Your integration might need data within Sugar&amp;#39;s module structure that could potentially change over time, so you can use Metadata for it as well as CRUD onto Sugar.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.48-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Metadata
&lt;ul&gt;
&lt;li&gt;Endpoint with current system&amp;#39;s structure&lt;/li&gt;
&lt;li&gt;Modules, fields, relationships, layouts&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Use carefully, its payload can be MBs in size, cache as much as possible&lt;/li&gt;
&lt;li&gt;GET /metadata (use filters as much as possible)&lt;/li&gt;
&lt;li&gt;It does not retrieve labels for dropdowns, use language API to do so&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/3-tips-for-using-the-sugar-metadata-api"&gt;3 Tips for using the Sugar Metadata API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Language
&lt;ul&gt;
&lt;li&gt;Endpoint to retrieve labels&lt;/li&gt;
&lt;li&gt;Dropdown list values&lt;/li&gt;
&lt;li&gt;Any language-specific content&lt;/li&gt;
&lt;li&gt;GET /lang/&amp;lt;language_code&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CRUD (Create, Read, Update, Delete) records
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_GET"&gt;Read&lt;/a&gt;: &lt;code&gt;GET /&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/module_POST"&gt;Create&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_PUT"&gt;Update&lt;/a&gt;: &lt;code&gt;PUT&amp;nbsp;&lt;span&gt;/&amp;lt;module&amp;gt;/:record&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_DELETE"&gt;Delete&lt;/a&gt;: &lt;code&gt;DELETE&amp;nbsp;/&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_POST"&gt;Filter&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;/filter&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;You can use &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_GET"&gt;GET&lt;/a&gt; as well&lt;/li&gt;
&lt;li&gt;POST solves the issue when a query is too long and hits HTTP limits&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_name_GET"&gt;Retrieve records related to another module&lt;/a&gt;:&amp;nbsp;&lt;code&gt;GET /&amp;lt;module&amp;gt;/:record/link/:link_name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_nameremote_id_POST"&gt;Creates a relationship to a pre-existing record:&lt;/a&gt;&lt;code&gt; POST /&amp;lt;module&amp;gt;/:record/link/:link_name/:remote_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="performance"&gt;&lt;/a&gt;Performance and Best Practices&lt;/h1&gt;
&lt;div class="row"&gt;
&lt;div class="col-xs-12 col-md-9"&gt;
&lt;p&gt;As you deep dive into Sugar APIs,&amp;nbsp;you will see how easy it is to integrate to pull and push data from and to Sugar and your systems, however, you must consider performance so your integration doesn&amp;#39;t become a bottleneck between those systems.&lt;/p&gt;
&lt;p&gt;You should consider the following guidelines when implementing your integrations:&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/268x140/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.44.04-AM.png" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Use Sugar&amp;#39;s sync_key to link to remote IDs
&lt;ul&gt;
&lt;li&gt;Sugar provides in every module a sync_key field&lt;/li&gt;
&lt;li&gt;sync_key is a unique identifier for that module that links back to your external system&amp;#39;s generated key&lt;/li&gt;
&lt;li&gt;For example, account ID from ERP is AC0001, set sync_key (pass as a parameter in the POST) and sugar will create a record in account with sync_key=AC0001&lt;/li&gt;
&lt;li&gt;Next patch/update, sugar will check &amp;quot;where sync_key=&amp;#39;AC0001&amp;#39;&amp;quot; and update it (it is indexed)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Integrate Upsert APIs
&lt;ul&gt;
&lt;li&gt;Sugar&amp;#39;s &amp;quot;update or insert&amp;quot; API based on sync_key&lt;/li&gt;
&lt;li&gt;Simplifies a common operation - if record exists, update it, otherwise create it (GET followed by a&amp;nbsp;PUT or POST)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_PATCH"&gt;Upsert by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_GET"&gt;Get by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_DELETE"&gt;Delete by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulerecord_idsync_key_field_namesync_key_field_value_PATCH"&gt;Set a sync on existing record (without sync_key)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_POST"&gt;Create relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_DELETE"&gt;Delete relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Bulk API
&lt;ul&gt;
&lt;li&gt;An endpoint that encapsulates multiple API calls into one single HTTP request&lt;/li&gt;
&lt;li&gt;Requests are executed synchronously (one after the other)&lt;/li&gt;
&lt;li&gt;Reducing network latency between calls&lt;/li&gt;
&lt;li&gt;Combined with Upsert provides the best performance&lt;/li&gt;
&lt;li&gt;Careful not to add too many requests to it&lt;/li&gt;
&lt;li&gt;Start small (5 to 10 requests) and increase until you reach its max capacity&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Polling and filtering time-based with Filter API
&lt;ul&gt;
&lt;li&gt;Integration gateway (or your external system) asks Sugar every X minutes&lt;/li&gt;
&lt;li&gt;Request Filter API using &lt;code&gt;max_num&lt;/code&gt; (max number of records), offset and fields&lt;/li&gt;
&lt;li&gt;The response will provide the data as well as &lt;code&gt;next_offset&lt;/code&gt; (offset can be seen as pagination)&lt;/li&gt;
&lt;li&gt;if &lt;code&gt;next_offset&lt;/code&gt; is -1, no more records to go through&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Initial Data Load into Sugar&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Use Bulk + Upsert to achieve data loads&lt;/li&gt;
&lt;li&gt;Millions&amp;nbsp;of records may take a little while to process, plan ahead (over the weekend)&lt;/li&gt;
&lt;li&gt;Use multi-thread processes to load (for example 20 threads sending 20 bulk upsert requests)&lt;/li&gt;
&lt;li&gt;Careful with&amp;nbsp;&lt;a href="https://support.sugarcrm.com/Resources/Sugar_Cloud_Policy_Guide/#Rate_Limits"&gt;Sugar Cloud rate limits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;It&amp;#39;s always a good idea to let Sugar Support know you&amp;#39;re data loading, they will be considerate.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Understanding PHP limitations&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;PHP is single-threaded with limited resources to process your request&lt;/li&gt;
&lt;li&gt;If you send too much data using bulk, you may run out of memory for that request&lt;/li&gt;
&lt;li&gt;Push to the limits but give some room for PHP to finish the request gracefully&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3 id="mcetoc_1f5uvkqns0"&gt;&lt;span style="font-size:inherit;"&gt;You&amp;#39;re up and running, but don&amp;#39;t stop now - this is just the beginning of your journey. Now it&amp;#39;s time to &lt;a href="/dev-club/dev-onboarding/w/documentation/686/customization-for-devs"&gt;Customizations&lt;/a&gt;.&lt;/span&gt;&lt;/h3&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Integrations for Devs</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs/revision/22</link><pubDate>Thu, 21 Jul 2022 18:49:00 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:df5ca10a-d211-4e03-9873-9d48feb7b645</guid><dc:creator>Matt Marum</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs#comments</comments><description>Revision 22 posted to Dev Tutorials by Matt Marum on 7/21/2022 6:49:00 PM&lt;br /&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="#approach"&gt;&lt;img alt=" " src="/resized-image/__size/269x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.42.25-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#rest"&gt;&lt;img alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.33-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#common"&gt;&lt;img alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.48-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#performance"&gt;&lt;img alt=" " src="/resized-image/__size/268x140/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.44.04-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="approach"&gt;&lt;/a&gt;Integration Approaches&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;The Sugar platform is extremely powerful, flexible, and allows for easy integration. This flexibility means that determining the&amp;nbsp;best approach for your use case scenario is the key to success.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/269x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.42.25-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Push/Pull from Sugar via REST API&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="text-decoration:underline;"&gt;Recommended&lt;/span&gt; approach&lt;/li&gt;
&lt;li&gt;Developers have full control over integration&lt;/li&gt;
&lt;li&gt;Integration can be stopped and systems will continue to work&lt;/li&gt;
&lt;li&gt;Retry mechanism: Resume integrations at any time (identify deltas through &amp;quot;last_update_time&amp;quot; flags)&lt;/li&gt;
&lt;li&gt;The time delay from/to Sugar is minimal&lt;/li&gt;
&lt;li&gt;Sugar REST API offers almost everything you need,&amp;nbsp;and can be further extended via customization&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Push to Sugar, Sugar pushes to an external queue in realtime&lt;span&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;Use Sugar Events to trigger through Logic Hooks&lt;/li&gt;
&lt;li&gt;Requires&amp;nbsp;Logic Hooks (code customization) to be created and deployed&lt;/li&gt;
&lt;li&gt;Does not offer a &amp;quot;retry mechanism&amp;quot;, if a logic hook fails to deliver to a queue or contact an external system&lt;/li&gt;
&lt;li&gt;Synchronous in nature, requires a response from an external system&lt;/li&gt;
&lt;li&gt;Needs to handle dependencies manually (contact can only be created after account)&lt;/li&gt;
&lt;li&gt;Good to have a middleware/queue in front of Sugar to receive those event triggers to&amp;nbsp;reliably&amp;nbsp;manage peak loads&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Realtime: Embed your app into Sugar&amp;nbsp;through &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/User_Interface/Dashlets/"&gt;Dashlets&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Simplest approach&lt;/li&gt;
&lt;li&gt;Often requires web user-based authentication&lt;/li&gt;
&lt;li&gt;All load/traffic goes directly to your system,&amp;nbsp;which makes your system the performance bottleneck&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="rest"&gt;&lt;/a&gt;REST API Webservices&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Accessing your data when you want is good. Accessing your data however you want is better. &lt;/span&gt;&lt;span&gt;When you decide to build an integration with Sugar, you&amp;rsquo;ll need an easy way to access and interact with the data stored in Sugar. The REST (&lt;/span&gt;&lt;span&gt;representational state transfer)&lt;/span&gt;&lt;span&gt;&amp;nbsp;API (application programming interface) is perfect for this.&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sugar REST API Overview
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;Fully RESTfull (GET, POST, PUT, DELETE)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;OAuth2 token based&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;All fields and modules are available through the API automatically&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Metadata API provides everything you need to know about your Sugar instance.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.33-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Topics
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/new-tutorial-intro-to-the-sugar-rest-api"&gt;Intro to the Sugar REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/how-sugar-rest-api-versioning-works"&gt;How Sugar REST API versioning works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/"&gt;RestAPI Developer Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/sugarcrm-cookbook---the-school-of-rest---part-1"&gt;School of REST blog series&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/"&gt;REST APIs Endpoints&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Extending_Endpoints/"&gt;How to add your own custom endpoints to the REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/API_Exceptions/"&gt;API Exceptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Best_Practices/"&gt;Best practices when integrating and migrating Sugar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="common"&gt;&lt;/a&gt;Common&amp;nbsp;APIs&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;It is important to understand our most commonly used APIs and their functions within Sugar. Your integration might need data within Sugar&amp;#39;s module structure that could potentially change over time, so you can use Metadata for it as well as CRUD onto Sugar.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.48-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Metadata
&lt;ul&gt;
&lt;li&gt;Endpoint with current system&amp;#39;s structure&lt;/li&gt;
&lt;li&gt;Modules, fields, relationships, layouts&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Use carefully, its payload can be MBs in size, cache as much as possible&lt;/li&gt;
&lt;li&gt;GET /metadata (use filters as much as possible)&lt;/li&gt;
&lt;li&gt;It does not retrieve labels for dropdowns, use language API to do so&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/3-tips-for-using-the-sugar-metadata-api"&gt;3 Tips for using the Sugar Metadata API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Language
&lt;ul&gt;
&lt;li&gt;Endpoint to retrieve labels&lt;/li&gt;
&lt;li&gt;Dropdown list values&lt;/li&gt;
&lt;li&gt;Any language-specific content&lt;/li&gt;
&lt;li&gt;GET /lang/&amp;lt;language_code&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CRUD (Create, Read, Update, Delete) records
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_GET"&gt;Read&lt;/a&gt;: &lt;code&gt;GET /&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/module_POST"&gt;Create&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_PUT"&gt;Update&lt;/a&gt;: &lt;code&gt;PUT&amp;nbsp;&lt;span&gt;/&amp;lt;module&amp;gt;/:record&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_DELETE"&gt;Delete&lt;/a&gt;: &lt;code&gt;DELETE&amp;nbsp;/&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_POST"&gt;Filter&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;/filter&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;You can use &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_GET"&gt;GET&lt;/a&gt; as well&lt;/li&gt;
&lt;li&gt;POST solves the issue when a query is too long and hits HTTP limits&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_name_GET"&gt;Retrieve records related to another module&lt;/a&gt;:&amp;nbsp;&lt;code&gt;GET /&amp;lt;module&amp;gt;/:record/link/:link_name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_nameremote_id_POST"&gt;Creates a relationship to a pre-existing record:&lt;/a&gt;&lt;code&gt; POST /&amp;lt;module&amp;gt;/:record/link/:link_name/:remote_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="performance"&gt;&lt;/a&gt;Performance and Best Practices&lt;/h1&gt;
&lt;div class="row"&gt;
&lt;div class="col-xs-12 col-md-9"&gt;
&lt;p&gt;As you deep dive into Sugar APIs,&amp;nbsp;you will see how easy it is to integrate to pull and push data from and to Sugar and your systems, however, you must consider performance so your integration doesn&amp;#39;t become a bottleneck between those systems.&lt;/p&gt;
&lt;p&gt;You should consider the following guidelines when implementing your integrations:&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/268x140/__key/communityserver-wikis-components-files/00-00-00-00-14/Screen-Shot-2022_2D00_07_2D00_14-at-11.44.04-AM.png" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Use Sugar&amp;#39;s sync_key to link to remote IDs
&lt;ul&gt;
&lt;li&gt;Sugar provides in every module a sync_key field&lt;/li&gt;
&lt;li&gt;sync_key is a unique identifier for that module that links back to your external system&amp;#39;s generated key&lt;/li&gt;
&lt;li&gt;For example, account ID from ERP is AC0001, set sync_key (pass as a parameter in the POST) and sugar will create a record in account with sync_key=AC0001&lt;/li&gt;
&lt;li&gt;Next patch/update, sugar will check &amp;quot;where sync_key=&amp;#39;AC0001&amp;#39;&amp;quot; and update it (it is indexed)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Integrate Upsert APIs
&lt;ul&gt;
&lt;li&gt;Sugar&amp;#39;s &amp;quot;update or insert&amp;quot; API based on sync_key&lt;/li&gt;
&lt;li&gt;Simplifies a common operation - if record exists, update it, otherwise create it (GET followed by a&amp;nbsp;PUT or POST)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_PATCH"&gt;Upsert by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_GET"&gt;Get by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_DELETE"&gt;Delete by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulerecord_idsync_key_field_namesync_key_field_value_PATCH"&gt;Set a sync on existing record (without sync_key)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_POST"&gt;Create relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_DELETE"&gt;Delete relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Bulk API
&lt;ul&gt;
&lt;li&gt;An endpoint that encapsulates multiple API calls into one single HTTP request&lt;/li&gt;
&lt;li&gt;Requests are executed synchronously (one after the other)&lt;/li&gt;
&lt;li&gt;Reducing network latency between calls&lt;/li&gt;
&lt;li&gt;Combined with Upsert provides the best performance&lt;/li&gt;
&lt;li&gt;Careful not to add too many requests to it&lt;/li&gt;
&lt;li&gt;Start small (5 to 10 requests) and increase until you reach its max capacity&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Polling and filtering time-based with Filter API
&lt;ul&gt;
&lt;li&gt;Integration gateway (or your external system) asks Sugar every X minutes&lt;/li&gt;
&lt;li&gt;Request Filter API using &lt;code&gt;max_num&lt;/code&gt; (max number of records), offset and fields&lt;/li&gt;
&lt;li&gt;The response will provide the data as well as &lt;code&gt;next_offset&lt;/code&gt; (offset can be seen as pagination)&lt;/li&gt;
&lt;li&gt;if &lt;code&gt;next_offset&lt;/code&gt; is -1, no more records to go through&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Initial Data Load into Sugar&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Use Bulk + Upsert to achieve data loads&lt;/li&gt;
&lt;li&gt;Millions&amp;nbsp;of records may take a little while to process, plan ahead (over the weekend)&lt;/li&gt;
&lt;li&gt;Use multi-thread processes to load (for example 20 threads sending 20 bulk upsert requests)&lt;/li&gt;
&lt;li&gt;Careful with&amp;nbsp;&lt;a href="https://support.sugarcrm.com/Resources/Sugar_Cloud_Policy_Guide/#Rate_Limits"&gt;Sugar Cloud rate limits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;It&amp;#39;s always a good idea to let Sugar Support know you&amp;#39;re data loading, they will be considerate.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Understanding PHP limitations&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;PHP is single-threaded with limited resources to process your request&lt;/li&gt;
&lt;li&gt;If you send too much data using bulk, you may run out of memory for that request&lt;/li&gt;
&lt;li&gt;Push to the limits but give some room for PHP to finish the request gracefully&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3 id="mcetoc_1f5uvkqns0"&gt;&lt;span style="font-size:inherit;"&gt;You&amp;#39;re up and running, but don&amp;#39;t stop now - this is just the beginning of your journey. Now it&amp;#39;s time to &lt;a href="/dev-club/dev-onboarding/w/documentation/686/customization-for-devs"&gt;Customizations&lt;/a&gt;.&lt;/span&gt;&lt;/h3&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Integrations for Devs</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs/revision/20</link><pubDate>Thu, 14 Jul 2022 20:28:02 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:df5ca10a-d211-4e03-9873-9d48feb7b645</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs#comments</comments><description>Revision 20 posted to Dev Tutorials by Rafael Fernandes on 7/14/2022 8:28:02 PM&lt;br /&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="#approach"&gt;&lt;img alt=" " src="/resized-image/__size/269x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.42.25-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#rest"&gt;&lt;img alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.33-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#common"&gt;&lt;img alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.48-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#performance"&gt;&lt;img alt=" " src="/resized-image/__size/268x140/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.44.04-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="approach"&gt;&lt;/a&gt;Integration Approaches&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;Sugar platform is extremely powerful and easy to integrate with. Determining the right approach for your use case scenario is the key to success.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/269x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.42.25-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Push/Pull from Sugar via REST API&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Recommended approach&lt;/li&gt;
&lt;li&gt;Developers have full control over integration&lt;/li&gt;
&lt;li&gt;Integration can be stopped and systems will continue to work&lt;/li&gt;
&lt;li&gt;Retry mechanism: Resume integrations at any time (bringing only delta changes through &amp;quot;last_udpdate_time&amp;quot; flags)&lt;/li&gt;
&lt;li&gt;Time delay from/to Sugar is minimum and bearable&lt;/li&gt;
&lt;li&gt;Sugar REST API offers everything you need, but can be extended&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Push to Sugar, Sugar pushes to external queue in realtime&lt;span&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;Uses Sugar Events to trigger through Logic Hooks&lt;/li&gt;
&lt;li&gt;Requires&amp;nbsp;Logic Hooks to be created and deployed&lt;/li&gt;
&lt;li&gt;Does not offer &amp;quot;retry mechanism&amp;quot;, if a logic hook fails to deliver to a queue or contact external system&lt;/li&gt;
&lt;li&gt;Synchronous in nature, requires a response from external system&lt;/li&gt;
&lt;li&gt;Needs to handle dependencies manually (contact can only be created after account)&lt;/li&gt;
&lt;li&gt;Good to have a middleware/queue in front of Sugar to receive those event triggers (not mandatory but would make it &amp;quot;asynchronous&amp;quot;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Realtime: Embed your app into Sugar&amp;nbsp;through &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/User_Interface/Dashlets/"&gt;Dashlets&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Simplest approach&lt;/li&gt;
&lt;li&gt;Often requires user-based authentication&lt;/li&gt;
&lt;li&gt;All load/traffic goes directly to your system,&amp;nbsp;careful with&amp;nbsp;bottlenecks&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="rest"&gt;&lt;/a&gt;REST API Webservices&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Accessing your data when you want is good. &amp;nbsp;Accessing your data however you want is better. &lt;/span&gt;&lt;span&gt;When you decide to build an integration with Sugar, you&amp;rsquo;ll need an easy way to access and interact with the data stored in Sugar. The REST (&lt;/span&gt;&lt;span&gt;representational state transfer)&lt;/span&gt;&lt;span&gt;&amp;nbsp;API (application programming interface) is perfect for this.&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sugar REST API Overview
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;Fully RESTfull (GET, POST, PUT, DELETE)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;OAuth2 token based&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;All fields and modules are available through the API automatically&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Metadata API provides everything you need to know about your Sugar instance.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.33-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Topics
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/new-tutorial-intro-to-the-sugar-rest-api"&gt;Intro to the Sugar REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/how-sugar-rest-api-versioning-works"&gt;How Sugar REST API versioning works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/"&gt;RestAPI Developer Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/sugarcrm-cookbook---the-school-of-rest---part-1"&gt;School of REST blog series&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/"&gt;REST APIs Endpoints&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Extending_Endpoints/"&gt;How to add your own custom endpoints to the REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/API_Exceptions/"&gt;API Exceptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Best_Practices/"&gt;Best practices when integrating and migrating Sugar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="common"&gt;&lt;/a&gt;Common&amp;nbsp;APIs&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;It is important to understand our most commonly used APIs and their functions within Sugar. Your integration might need data within Sugar&amp;#39;s module structure that could potentially change over time, so you can use Metadata for it as well as CRUD onto Sugar.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.48-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Metadata
&lt;ul&gt;
&lt;li&gt;Endpoint with current system&amp;#39;s structure&lt;/li&gt;
&lt;li&gt;Modules, fields, relationships, layouts&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Use carefully, its payload can be MBs in size, cache as much as possible&lt;/li&gt;
&lt;li&gt;GET /metadata (use filters as much as possible)&lt;/li&gt;
&lt;li&gt;It does not retrieve lables for dropdowns, use language api to do so&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/3-tips-for-using-the-sugar-metadata-api"&gt;3 Tips for using the Sugar Metadata API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Language
&lt;ul&gt;
&lt;li&gt;Endpoint to retrieve labels&lt;/li&gt;
&lt;li&gt;Dropdown list values&lt;/li&gt;
&lt;li&gt;Any language specific content&lt;/li&gt;
&lt;li&gt;GET /lang/&amp;lt;language_code&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CRUD (Create, Read, Update, Delete) records
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_GET"&gt;Read&lt;/a&gt;: &lt;code&gt;GET /&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/module_POST"&gt;Create&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_PUT"&gt;Update&lt;/a&gt;: &lt;code&gt;PUT&amp;nbsp;&lt;span&gt;/&amp;lt;module&amp;gt;/:record&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_DELETE"&gt;Delete&lt;/a&gt;: &lt;code&gt;DELETE&amp;nbsp;/&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_POST"&gt;Filter&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;/filter&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;You can use &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_GET"&gt;GET&lt;/a&gt; as well&lt;/li&gt;
&lt;li&gt;POST solves the issue when a query is too long and hits HTTP limits&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_name_GET"&gt;Retrieve records related to another module&lt;/a&gt;:&amp;nbsp;&lt;code&gt;GET /&amp;lt;module&amp;gt;/:record/link/:link_name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_nameremote_id_POST"&gt;Creates a relationship to a pre-existing record:&lt;/a&gt;&lt;code&gt; POST /&amp;lt;module&amp;gt;/:record/link/:link_name/:remote_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="performance"&gt;&lt;/a&gt;Performance and Best Practices&lt;/h1&gt;
&lt;div class="row"&gt;
&lt;div class="col-xs-12 col-md-9"&gt;
&lt;p&gt;As you deep dive into Sugar APIs,&amp;nbsp;you will see how easy it is to integrate to pull and push data from and to Sugar and your systems, however, you must consider performance so your integration doesn&amp;#39;t become a bottleneck between those systems.&lt;/p&gt;
&lt;p&gt;You should consider the following guidelines when implementing your integrations:&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/268x140/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.44.04-AM.png" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Use Sugar&amp;#39;s sync_key
&lt;ul&gt;
&lt;li&gt;Sugar provides in every module a sync_key field&lt;/li&gt;
&lt;li&gt;sync_key is a unique identifier for that module that links back to your external system&amp;#39;s generated key&lt;/li&gt;
&lt;li&gt;For example, account ID from ERP is AC0001, set sync_key (pass as parameter in the POST) and sugar will create a record in account with sync_key=AC0001&lt;/li&gt;
&lt;li&gt;Next patch/update, sugar will check &amp;quot;where sync_key=&amp;#39;AC0001&amp;#39;&amp;quot; and update it (it is indexed)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Integrate Upsert APIs
&lt;ul&gt;
&lt;li&gt;Sugar&amp;#39;s &amp;quot;update or insert&amp;quot; API based on sync_key&lt;/li&gt;
&lt;li&gt;Replaces commonly used check if exists, update or create (GET and POST or PUT)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_PATCH"&gt;Upsert by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_GET"&gt;Get by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_DELETE"&gt;Delete by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulerecord_idsync_key_field_namesync_key_field_value_PATCH"&gt;Set a sync on existing record (without sync_key)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_POST"&gt;Create relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_DELETE"&gt;Delete relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Bulk API
&lt;ul&gt;
&lt;li&gt;Endpoint that encapsulates multiple API calls into one single HTTP request&lt;/li&gt;
&lt;li&gt;Requests are executed synchronously (one after the other)&lt;/li&gt;
&lt;li&gt;Reducing network latency between calls&lt;/li&gt;
&lt;li&gt;Combined with Upsert provides the best performance&lt;/li&gt;
&lt;li&gt;Careful not to add too many requests to it&lt;/li&gt;
&lt;li&gt;Start small (5 to 10 requests) and increase until you reach it&amp;#39;s max capacity&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Polling and filtering time-based with Filter API
&lt;ul&gt;
&lt;li&gt;Integration gateway (or your external system) asks Sugar every X minutes&lt;/li&gt;
&lt;li&gt;Request Filter API using &lt;code&gt;max_num&lt;/code&gt; (max number of records), offset and fields&lt;/li&gt;
&lt;li&gt;Response will provide the data as well as &lt;code&gt;next_offset&lt;/code&gt; (offset can be seen as pagination)&lt;/li&gt;
&lt;li&gt;if &lt;code&gt;next_offset&lt;/code&gt; is -1, no more records to go through&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Initial Data Load into Sugar&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Use Bulk + Upsert to achieve data loads&lt;/li&gt;
&lt;li&gt;Millions&amp;nbsp;of records may take a little while to process, plan ahead (over the weekend)&lt;/li&gt;
&lt;li&gt;Use multi-thread processes to load (for example 20 threads sending 20 bulk upsert requests)&lt;/li&gt;
&lt;li&gt;Careful with&amp;nbsp;&lt;a href="https://support.sugarcrm.com/Resources/Sugar_Cloud_Policy_Guide/#Rate_Limits"&gt;Sugar Cloud rate limits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;It&amp;#39;s always a good idea to let Sugar Support know you&amp;#39;re data loading, they will be considerate.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Understanding PHP limitations&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;PHP is single threaded with limited resources to process your request&lt;/li&gt;
&lt;li&gt;If you send too much data using bulk, you may run out of memory for that request&lt;/li&gt;
&lt;li&gt;Push to the limits but give some room for PHP to finish the request gracefully&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3 id="mcetoc_1f5uvkqns0"&gt;&lt;span style="font-size:inherit;"&gt;You&amp;#39;re up and running, but don&amp;#39;t stop now - this is just the beginning of your journey. Now it&amp;#39;s time to &lt;a href="/dev-club/dev-onboarding/w/documentation/686/customization-for-devs"&gt;Customizations&lt;/a&gt;.&lt;/span&gt;&lt;/h3&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Integrations for Devs</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs/revision/19</link><pubDate>Thu, 14 Jul 2022 15:51:01 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:df5ca10a-d211-4e03-9873-9d48feb7b645</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs#comments</comments><description>Revision 19 posted to Dev Tutorials by Rafael Fernandes on 7/14/2022 3:51:01 PM&lt;br /&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="#approach"&gt;&lt;img alt=" " src="/resized-image/__size/269x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.42.25-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#rest"&gt;&lt;img alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.33-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#common"&gt;&lt;img alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.48-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#performance"&gt;&lt;img alt=" " src="/resized-image/__size/268x140/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.44.04-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="approach"&gt;&lt;/a&gt;Integration Approaches&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;Sugar platform is extremely powerful and easy to integrate with. Determining the right approach for your use case scenario is the key to success.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/269x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.42.25-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Push/Pull from Sugar via REST API&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Recommended approach&lt;/li&gt;
&lt;li&gt;Developers have full control over integration&lt;/li&gt;
&lt;li&gt;Integration can be stopped and systems will continue to work&lt;/li&gt;
&lt;li&gt;Retry mechanism: Resume integrations at any time (bringing only delta changes through &amp;quot;last_udpdate_time&amp;quot; flags)&lt;/li&gt;
&lt;li&gt;Time delay from/to Sugar is minimum and bearable&lt;/li&gt;
&lt;li&gt;Sugar REST API offers everything you need, but can be extended&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Push to Sugar, Sugar pushes to external queue in realtime&lt;span&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;Uses Sugar Events to trigger through Logic Hooks&lt;/li&gt;
&lt;li&gt;Requires&amp;nbsp;Logic Hooks to be created and deployed&lt;/li&gt;
&lt;li&gt;Does not offer &amp;quot;retry mechanism&amp;quot;, if a logic hook fails to deliver to a queue or contact external system&lt;/li&gt;
&lt;li&gt;Synchronous in nature, requires a response from external system&lt;/li&gt;
&lt;li&gt;Needs to handle dependencies manually (contact can only be created after account)&lt;/li&gt;
&lt;li&gt;Good to have a middleware/queue in front of Sugar to receive those event triggers (not mandatory but would make it &amp;quot;asynchronous&amp;quot;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Realtime: Embed your app into Sugar&amp;nbsp;through &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/User_Interface/Dashlets/"&gt;Dashlets&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Simplest approach&lt;/li&gt;
&lt;li&gt;Often requires user-based authentication&lt;/li&gt;
&lt;li&gt;All load/traffic goes directly to your system,&amp;nbsp;careful with&amp;nbsp;bottlenecks&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="rest"&gt;&lt;/a&gt;REST API Webservices&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Accessing your data when you want is good. &amp;nbsp;Accessing your data however you want is better. &lt;/span&gt;&lt;span&gt;When you decide to build an integration with Sugar, you&amp;rsquo;ll need an easy way to access and interact with the data stored in Sugar. The REST (&lt;/span&gt;&lt;span&gt;representational state transfer)&lt;/span&gt;&lt;span&gt;&amp;nbsp;API (application programming interface) is perfect for this.&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sugar REST API Overview
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;Fully RESTfull (GET, POST, PUT, DELETE)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;OAuth2 token based&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;All fields and modules are available through the API automatically&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Metadata API provides everything you need to know about your Sugar instance.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.33-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Topics
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/new-tutorial-intro-to-the-sugar-rest-api"&gt;Intro to the Sugar REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/how-sugar-rest-api-versioning-works"&gt;How Sugar REST API versioning works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/"&gt;RestAPI Developer Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/sugarcrm-cookbook---the-school-of-rest---part-1"&gt;School of REST blog series&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/"&gt;REST APIs Endpoints&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Extending_Endpoints/"&gt;How to add your own custom endpoints to the REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/API_Exceptions/"&gt;API Exceptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Best_Practices/"&gt;Best practices when integrating and migrating Sugar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="common"&gt;&lt;/a&gt;Common&amp;nbsp;APIs&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;It is important to understand our most commonly used APIs and their functions within Sugar. Your integration might need data within Sugar&amp;#39;s module structure that could potentially change over time, so you can use Metadata for it as well as CRUD onto Sugar.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.48-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Metadata
&lt;ul&gt;
&lt;li&gt;Endpoint with current system&amp;#39;s structure&lt;/li&gt;
&lt;li&gt;Modules, fields, relationships, layouts&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Use carefully, its payload can be MBs in size, cache as much as possible&lt;/li&gt;
&lt;li&gt;GET /metadata (use filters as much as possible)&lt;/li&gt;
&lt;li&gt;It does not retrieve lables for dropdowns, use language api to do so&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/3-tips-for-using-the-sugar-metadata-api"&gt;3 Tips for using the Sugar Metadata API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Language
&lt;ul&gt;
&lt;li&gt;Endpoint to retrieve labels&lt;/li&gt;
&lt;li&gt;Dropdown list values&lt;/li&gt;
&lt;li&gt;Any language specific content&lt;/li&gt;
&lt;li&gt;GET /lang/&amp;lt;language_code&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CRUD (Create, Read, Update, Delete) records
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_GET"&gt;Read&lt;/a&gt;: &lt;code&gt;GET /&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/module_POST"&gt;Create&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_PUT"&gt;Update&lt;/a&gt;: &lt;code&gt;PUT&amp;nbsp;&lt;span&gt;/&amp;lt;module&amp;gt;/:record&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_DELETE"&gt;Delete&lt;/a&gt;: &lt;code&gt;DELETE&amp;nbsp;/&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_POST"&gt;Filter&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;/filter&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;You can use &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_GET"&gt;GET&lt;/a&gt; as well&lt;/li&gt;
&lt;li&gt;POST solves the issue when a query is too long and hits HTTP limits&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_name_GET"&gt;Retrieve records related to another module&lt;/a&gt;:&amp;nbsp;&lt;code&gt;GET /&amp;lt;module&amp;gt;/:record/link/:link_name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_nameremote_id_POST"&gt;Creates a relationship to a pre-existing record:&lt;/a&gt;&lt;code&gt; POST /&amp;lt;module&amp;gt;/:record/link/:link_name/:remote_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="performance"&gt;&lt;/a&gt;Performance and Best Practices&lt;/h1&gt;
&lt;div class="row"&gt;
&lt;div class="col-xs-12 col-md-9"&gt;
&lt;p&gt;As you deep dive into Sugar APIs,&amp;nbsp;you will see how easy it is to integrate to pull and push data from and to Sugar and your systems, however, you must consider performance so your integration doesn&amp;#39;t become a bottleneck between those systems.&lt;/p&gt;
&lt;p&gt;You should consider the following guidelines when implementing your integrations:&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/268x140/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.44.04-AM.png" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Use Sugar&amp;#39;s sync_key
&lt;ul&gt;
&lt;li&gt;Sugar provides in every module a sync_key field&lt;/li&gt;
&lt;li&gt;sync_key is a unique identifier for that module that links back to your external system&amp;#39;s generated key&lt;/li&gt;
&lt;li&gt;For example, account ID from ERP is AC0001, set sync_key (pass as parameter in the POST) and sugar will create a record in account with sync_key=AC0001&lt;/li&gt;
&lt;li&gt;Next patch/update, sugar will check &amp;quot;where sync_key=&amp;#39;AC0001&amp;#39;&amp;quot; and update it (it is indexed)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Integrate Upsert APIs
&lt;ul&gt;
&lt;li&gt;Sugar&amp;#39;s &amp;quot;update or insert&amp;quot; API based on sync_key&lt;/li&gt;
&lt;li&gt;Replaces commonly used check if exists, update or create (GET and POST or PUT)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_PATCH"&gt;Upsert by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_GET"&gt;Get by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_DELETE"&gt;Delete by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulerecord_idsync_key_field_namesync_key_field_value_PATCH"&gt;Set a sync on existing record (without sync_key)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_POST"&gt;Create relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_DELETE"&gt;Delete relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Bulk API
&lt;ul&gt;
&lt;li&gt;Endpoint that encapsulates multiple API calls into one single HTTP request&lt;/li&gt;
&lt;li&gt;Requests are executed synchronously (one after the other)&lt;/li&gt;
&lt;li&gt;Reducing network latency between calls&lt;/li&gt;
&lt;li&gt;Combined with Upsert provides the best performance&lt;/li&gt;
&lt;li&gt;Careful not to add too many requests to it&lt;/li&gt;
&lt;li&gt;Start small (5 to 10 requests) and increase until you reach it&amp;#39;s max capacity&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Polling and filtering time-based with Filter API
&lt;ul&gt;
&lt;li&gt;Integration gateway (or your external system) asks Sugar every X minutes&lt;/li&gt;
&lt;li&gt;Request Filter API using &lt;code&gt;max_num&lt;/code&gt; (max number of records), offset and fields&lt;/li&gt;
&lt;li&gt;Response will provide the data as well as &lt;code&gt;next_offset&lt;/code&gt; (offset can be seen as pagination)&lt;/li&gt;
&lt;li&gt;if &lt;code&gt;next_offset&lt;/code&gt; is -1, no more records to go through&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Initial Data Load into Sugar&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Use Bulk + Upsert to achieve data loads&lt;/li&gt;
&lt;li&gt;Millions&amp;nbsp;of records may take a little while to process, plan ahead (over the weekend)&lt;/li&gt;
&lt;li&gt;Use multi-thread processes to load (for example 20 threads sending 20 bulk upsert requests)&lt;/li&gt;
&lt;li&gt;Careful with&amp;nbsp;&lt;a href="https://support.sugarcrm.com/Resources/Sugar_Cloud_Policy_Guide/#Rate_Limits"&gt;Sugar Cloud rate limits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;It&amp;#39;s always a good idea to let Sugar Support know you&amp;#39;re data loading, they will be considerate.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Understanding PHP limitations
&lt;ul&gt;
&lt;li&gt;PHP allocates OS resources to process your request&lt;/li&gt;
&lt;li&gt;If you send too much data using bulk, you may run out of memory for that request&lt;/li&gt;
&lt;li&gt;Push to the limits but give some room for PHP to finish the request gracefully&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3 id="mcetoc_1f5uvkqns0"&gt;&lt;span style="font-size:inherit;"&gt;You&amp;#39;re up and running, but don&amp;#39;t stop now - this is just the beginning of your journey. Now it&amp;#39;s time to &lt;a href="/dev-club/dev-onboarding/w/documentation/686/customization-for-devs"&gt;Customizations&lt;/a&gt;.&lt;/span&gt;&lt;/h3&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Integrations for Devs</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs/revision/18</link><pubDate>Thu, 14 Jul 2022 15:44:15 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:df5ca10a-d211-4e03-9873-9d48feb7b645</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs#comments</comments><description>Revision 18 posted to Dev Tutorials by Rafael Fernandes on 7/14/2022 3:44:15 PM&lt;br /&gt;
&lt;p&gt;&lt;span style="background-color:#ff0000;font-size:150%;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="#register"&gt;&lt;img alt=" " src="/resized-image/__size/269x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.42.25-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#setup"&gt;&lt;img alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.33-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#api"&gt;&lt;img alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.48-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#learn"&gt;&lt;img alt=" " src="/resized-image/__size/268x140/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.44.04-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="setup"&gt;&lt;/a&gt;Integration Approaches&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;Sugar platform is extremely powerful and easy to integrate with. Determining the right approach for your use case scenario is the key to success.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/269x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.42.25-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Push/Pull from Sugar via REST API&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Recommended approach&lt;/li&gt;
&lt;li&gt;Developers have full control over integration&lt;/li&gt;
&lt;li&gt;Integration can be stopped and systems will continue to work&lt;/li&gt;
&lt;li&gt;Retry mechanism: Resume integrations at any time (bringing only delta changes through &amp;quot;last_udpdate_time&amp;quot; flags)&lt;/li&gt;
&lt;li&gt;Time delay from/to Sugar is minimum and bearable&lt;/li&gt;
&lt;li&gt;Sugar REST API offers everything you need, but can be extended&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Push to Sugar, Sugar pushes to external queue in realtime&lt;span&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;Uses Sugar Events to trigger through Logic Hooks&lt;/li&gt;
&lt;li&gt;Requires&amp;nbsp;Logic Hooks to be created and deployed&lt;/li&gt;
&lt;li&gt;Does not offer &amp;quot;retry mechanism&amp;quot;, if a logic hook fails to deliver to a queue or contact external system&lt;/li&gt;
&lt;li&gt;Synchronous in nature, requires a response from external system&lt;/li&gt;
&lt;li&gt;Needs to handle dependencies manually (contact can only be created after account)&lt;/li&gt;
&lt;li&gt;Good to have a middleware/queue in front of Sugar to receive those event triggers (not mandatory but would make it &amp;quot;asynchronous&amp;quot;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Realtime: Embed your app into Sugar&amp;nbsp;through &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/User_Interface/Dashlets/"&gt;Dashlets&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Simplest approach&lt;/li&gt;
&lt;li&gt;Often requires user-based authentication&lt;/li&gt;
&lt;li&gt;All load/traffic goes directly to your system,&amp;nbsp;careful with&amp;nbsp;bottlenecks&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="register"&gt;&lt;/a&gt;REST API Webservices&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Accessing your data when you want is good. &amp;nbsp;Accessing your data however you want is better. &lt;/span&gt;&lt;span&gt;When you decide to build an integration with Sugar, you&amp;rsquo;ll need an easy way to access and interact with the data stored in Sugar. The REST (&lt;/span&gt;&lt;span&gt;representational state transfer)&lt;/span&gt;&lt;span&gt;&amp;nbsp;API (application programming interface) is perfect for this.&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sugar REST API Overview
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;Fully RESTfull (GET, POST, PUT, DELETE)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;OAuth2 token based&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;All fields and modules are available through the API automatically&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Metadata API provides everything you need to know about your Sugar instance.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.33-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Topics
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/new-tutorial-intro-to-the-sugar-rest-api"&gt;Intro to the Sugar REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/how-sugar-rest-api-versioning-works"&gt;How Sugar REST API versioning works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/"&gt;RestAPI Developer Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/sugarcrm-cookbook---the-school-of-rest---part-1"&gt;School of REST blog series&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/"&gt;REST APIs Endpoints&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Extending_Endpoints/"&gt;How to add your own custom endpoints to the REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/API_Exceptions/"&gt;API Exceptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Best_Practices/"&gt;Best practices when integrating and migrating Sugar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="api"&gt;&lt;/a&gt;Common&amp;nbsp;APIs&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;It is important to understand our most commonly used APIs and their functions within Sugar. Your integration might need data within Sugar&amp;#39;s module structure that could potentially change over time, so you can use Metadata for it as well as CRUD onto Sugar.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.48-AM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Metadata
&lt;ul&gt;
&lt;li&gt;Endpoint with current system&amp;#39;s structure&lt;/li&gt;
&lt;li&gt;Modules, fields, relationships, layouts&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Use carefully, its payload can be MBs in size, cache as much as possible&lt;/li&gt;
&lt;li&gt;GET /metadata (use filters as much as possible)&lt;/li&gt;
&lt;li&gt;It does not retrieve lables for dropdowns, use language api to do so&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/3-tips-for-using-the-sugar-metadata-api"&gt;3 Tips for using the Sugar Metadata API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Language
&lt;ul&gt;
&lt;li&gt;Endpoint to retrieve labels&lt;/li&gt;
&lt;li&gt;Dropdown list values&lt;/li&gt;
&lt;li&gt;Any language specific content&lt;/li&gt;
&lt;li&gt;GET /lang/&amp;lt;language_code&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CRUD (Create, Read, Update, Delete) records
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_GET"&gt;Read&lt;/a&gt;: &lt;code&gt;GET /&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/module_POST"&gt;Create&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_PUT"&gt;Update&lt;/a&gt;: &lt;code&gt;PUT&amp;nbsp;&lt;span&gt;/&amp;lt;module&amp;gt;/:record&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_DELETE"&gt;Delete&lt;/a&gt;: &lt;code&gt;DELETE&amp;nbsp;/&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_POST"&gt;Filter&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;/filter&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;You can use &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_GET"&gt;GET&lt;/a&gt; as well&lt;/li&gt;
&lt;li&gt;POST solves the issue when a query is too long and hits HTTP limits&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_name_GET"&gt;Retrieve records related to another module&lt;/a&gt;:&amp;nbsp;&lt;code&gt;GET /&amp;lt;module&amp;gt;/:record/link/:link_name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_nameremote_id_POST"&gt;Creates a relationship to a pre-existing record:&lt;/a&gt;&lt;code&gt; POST /&amp;lt;module&amp;gt;/:record/link/:link_name/:remote_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="learn"&gt;&lt;/a&gt;Performance and Best Practices&lt;/h1&gt;
&lt;div class="row"&gt;
&lt;div class="col-xs-12 col-md-9"&gt;
&lt;p&gt;As you deep dive into Sugar APIs,&amp;nbsp;you will see how easy it is to integrate to pull and push data from and to Sugar and your systems, however, you must consider performance so your integration doesn&amp;#39;t become a bottleneck between those systems.&lt;/p&gt;
&lt;p&gt;You should consider the following guidelines when implementing your integrations:&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/268x140/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.44.04-AM.png" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Use Sugar&amp;#39;s sync_key
&lt;ul&gt;
&lt;li&gt;Sugar provides in every module a sync_key field&lt;/li&gt;
&lt;li&gt;sync_key is a unique identifier for that module that links back to your external system&amp;#39;s generated key&lt;/li&gt;
&lt;li&gt;For example, account ID from ERP is AC0001, set sync_key (pass as parameter in the POST) and sugar will create a record in account with sync_key=AC0001&lt;/li&gt;
&lt;li&gt;Next patch/update, sugar will check &amp;quot;where sync_key=&amp;#39;AC0001&amp;#39;&amp;quot; and update it (it is indexed)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Integrate Upsert APIs
&lt;ul&gt;
&lt;li&gt;Sugar&amp;#39;s &amp;quot;update or insert&amp;quot; API based on sync_key&lt;/li&gt;
&lt;li&gt;Replaces commonly used check if exists, update or create (GET and POST or PUT)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_PATCH"&gt;Upsert by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_GET"&gt;Get by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_DELETE"&gt;Delete by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulerecord_idsync_key_field_namesync_key_field_value_PATCH"&gt;Set a sync on existing record (without sync_key)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_POST"&gt;Create relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_DELETE"&gt;Delete relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Bulk API
&lt;ul&gt;
&lt;li&gt;Endpoint that encapsulates multiple API calls into one single HTTP request&lt;/li&gt;
&lt;li&gt;Requests are executed synchronously (one after the other)&lt;/li&gt;
&lt;li&gt;Reducing network latency between calls&lt;/li&gt;
&lt;li&gt;Combined with Upsert provides the best performance&lt;/li&gt;
&lt;li&gt;Careful not to add too many requests to it&lt;/li&gt;
&lt;li&gt;Start small (5 to 10 requests) and increase until you reach it&amp;#39;s max capacity&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Polling and filtering time-based with Filter API
&lt;ul&gt;
&lt;li&gt;Integration gateway (or your external system) asks Sugar every X minutes&lt;/li&gt;
&lt;li&gt;Request Filter API using &lt;code&gt;max_num&lt;/code&gt; (max number of records), offset and fields&lt;/li&gt;
&lt;li&gt;Response will provide the data as well as &lt;code&gt;next_offset&lt;/code&gt; (offset can be seen as pagination)&lt;/li&gt;
&lt;li&gt;if &lt;code&gt;next_offset&lt;/code&gt; is -1, no more records to go through&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Initial Data Load into Sugar&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Use Bulk + Upsert to achieve data loads&lt;/li&gt;
&lt;li&gt;Millions&amp;nbsp;of records may take a little while to process, plan ahead (over the weekend)&lt;/li&gt;
&lt;li&gt;Use multi-thread processes to load (for example 20 threads sending 20 bulk upsert requests)&lt;/li&gt;
&lt;li&gt;Careful with&amp;nbsp;&lt;a href="https://support.sugarcrm.com/Resources/Sugar_Cloud_Policy_Guide/#Rate_Limits"&gt;Sugar Cloud rate limits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;It&amp;#39;s always a good idea to let Sugar Support know you&amp;#39;re data loading, they will be considerate.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Understanding PHP limitations
&lt;ul&gt;
&lt;li&gt;PHP allocates OS resources to process your request&lt;/li&gt;
&lt;li&gt;If you send too much data using bulk, you may run out of memory for that request&lt;/li&gt;
&lt;li&gt;Push to the limits but give some room for PHP to finish the request gracefully&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3 id="mcetoc_1f5uvkqns0"&gt;&lt;span style="font-size:inherit;"&gt;You&amp;#39;re up and running, but don&amp;#39;t stop now - this is just the beginning of your journey. Now it&amp;#39;s time to &lt;a href="/dev-club/dev-onboarding/w/documentation/686/customization-for-devs"&gt;Customizations&lt;/a&gt;.&lt;/span&gt;&lt;/h3&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Integrations for Devs</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs/revision/17</link><pubDate>Thu, 14 Jul 2022 15:43:11 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:df5ca10a-d211-4e03-9873-9d48feb7b645</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs#comments</comments><description>Revision 17 posted to Dev Tutorials by Rafael Fernandes on 7/14/2022 3:43:11 PM&lt;br /&gt;
&lt;p&gt;&lt;span style="background-color:#ff0000;font-size:150%;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="#register"&gt;&lt;img alt=" " src="/resized-image/__size/269x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.42.25-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#setup"&gt;&lt;img alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.33-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#api"&gt;&lt;img alt=" " src="/resized-image/__size/270x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.43.48-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#learn"&gt;&lt;img alt=" " src="/resized-image/__size/268x140/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_07_2D00_14-at-11.44.04-AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="setup"&gt;&lt;/a&gt;Integration Approaches&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;Sugar platform is extremely powerful and easy to integrate with. Determining the right approach for your use case scenario is the key to success.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/263x136/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.00-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Push/Pull from Sugar via REST API&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Recommended approach&lt;/li&gt;
&lt;li&gt;Developers have full control over integration&lt;/li&gt;
&lt;li&gt;Integration can be stopped and systems will continue to work&lt;/li&gt;
&lt;li&gt;Retry mechanism: Resume integrations at any time (bringing only delta changes through &amp;quot;last_udpdate_time&amp;quot; flags)&lt;/li&gt;
&lt;li&gt;Time delay from/to Sugar is minimum and bearable&lt;/li&gt;
&lt;li&gt;Sugar REST API offers everything you need, but can be extended&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Push to Sugar, Sugar pushes to external queue in realtime&lt;span&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;Uses Sugar Events to trigger through Logic Hooks&lt;/li&gt;
&lt;li&gt;Requires&amp;nbsp;Logic Hooks to be created and deployed&lt;/li&gt;
&lt;li&gt;Does not offer &amp;quot;retry mechanism&amp;quot;, if a logic hook fails to deliver to a queue or contact external system&lt;/li&gt;
&lt;li&gt;Synchronous in nature, requires a response from external system&lt;/li&gt;
&lt;li&gt;Needs to handle dependencies manually (contact can only be created after account)&lt;/li&gt;
&lt;li&gt;Good to have a middleware/queue in front of Sugar to receive those event triggers (not mandatory but would make it &amp;quot;asynchronous&amp;quot;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Realtime: Embed your app into Sugar&amp;nbsp;through &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/User_Interface/Dashlets/"&gt;Dashlets&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Simplest approach&lt;/li&gt;
&lt;li&gt;Often requires user-based authentication&lt;/li&gt;
&lt;li&gt;All load/traffic goes directly to your system,&amp;nbsp;careful with&amp;nbsp;bottlenecks&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="register"&gt;&lt;/a&gt;REST API Webservices&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Accessing your data when you want is good. &amp;nbsp;Accessing your data however you want is better. &lt;/span&gt;&lt;span&gt;When you decide to build an integration with Sugar, you&amp;rsquo;ll need an easy way to access and interact with the data stored in Sugar. The REST (&lt;/span&gt;&lt;span&gt;representational state transfer)&lt;/span&gt;&lt;span&gt;&amp;nbsp;API (application programming interface) is perfect for this.&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sugar REST API Overview
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;Fully RESTfull (GET, POST, PUT, DELETE)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;OAuth2 token based&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;All fields and modules are available through the API automatically&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Metadata API provides everything you need to know about your Sugar instance.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/271x140/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.17.45-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Topics
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/new-tutorial-intro-to-the-sugar-rest-api"&gt;Intro to the Sugar REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/how-sugar-rest-api-versioning-works"&gt;How Sugar REST API versioning works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/"&gt;RestAPI Developer Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/sugarcrm-cookbook---the-school-of-rest---part-1"&gt;School of REST blog series&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/"&gt;REST APIs Endpoints&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Extending_Endpoints/"&gt;How to add your own custom endpoints to the REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/API_Exceptions/"&gt;API Exceptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Best_Practices/"&gt;Best practices when integrating and migrating Sugar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="api"&gt;&lt;/a&gt;Common&amp;nbsp;APIs&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;It is important to understand our most commonly used APIs and their functions within Sugar. Your integration might need data within Sugar&amp;#39;s module structure that could potentially change over time, so you can use Metadata for it as well as CRUD onto Sugar.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/273x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.20-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Metadata
&lt;ul&gt;
&lt;li&gt;Endpoint with current system&amp;#39;s structure&lt;/li&gt;
&lt;li&gt;Modules, fields, relationships, layouts&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Use carefully, its payload can be MBs in size, cache as much as possible&lt;/li&gt;
&lt;li&gt;GET /metadata (use filters as much as possible)&lt;/li&gt;
&lt;li&gt;It does not retrieve lables for dropdowns, use language api to do so&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/3-tips-for-using-the-sugar-metadata-api"&gt;3 Tips for using the Sugar Metadata API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Language
&lt;ul&gt;
&lt;li&gt;Endpoint to retrieve labels&lt;/li&gt;
&lt;li&gt;Dropdown list values&lt;/li&gt;
&lt;li&gt;Any language specific content&lt;/li&gt;
&lt;li&gt;GET /lang/&amp;lt;language_code&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CRUD (Create, Read, Update, Delete) records
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_GET"&gt;Read&lt;/a&gt;: &lt;code&gt;GET /&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/module_POST"&gt;Create&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_PUT"&gt;Update&lt;/a&gt;: &lt;code&gt;PUT&amp;nbsp;&lt;span&gt;/&amp;lt;module&amp;gt;/:record&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_DELETE"&gt;Delete&lt;/a&gt;: &lt;code&gt;DELETE&amp;nbsp;/&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_POST"&gt;Filter&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;/filter&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;You can use &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_GET"&gt;GET&lt;/a&gt; as well&lt;/li&gt;
&lt;li&gt;POST solves the issue when a query is too long and hits HTTP limits&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_name_GET"&gt;Retrieve records related to another module&lt;/a&gt;:&amp;nbsp;&lt;code&gt;GET /&amp;lt;module&amp;gt;/:record/link/:link_name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_nameremote_id_POST"&gt;Creates a relationship to a pre-existing record:&lt;/a&gt;&lt;code&gt; POST /&amp;lt;module&amp;gt;/:record/link/:link_name/:remote_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="learn"&gt;&lt;/a&gt;Performance and Best Practices&lt;/h1&gt;
&lt;div class="row"&gt;
&lt;div class="col-xs-12 col-md-9"&gt;
&lt;p&gt;As you deep dive into Sugar APIs,&amp;nbsp;you will see how easy it is to integrate to pull and push data from and to Sugar and your systems, however, you must consider performance so your integration doesn&amp;#39;t become a bottleneck between those systems.&lt;/p&gt;
&lt;p&gt;You should consider the following guidelines when implementing your integrations:&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/272x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.19.03-PM.png" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Use Sugar&amp;#39;s sync_key
&lt;ul&gt;
&lt;li&gt;Sugar provides in every module a sync_key field&lt;/li&gt;
&lt;li&gt;sync_key is a unique identifier for that module that links back to your external system&amp;#39;s generated key&lt;/li&gt;
&lt;li&gt;For example, account ID from ERP is AC0001, set sync_key (pass as parameter in the POST) and sugar will create a record in account with sync_key=AC0001&lt;/li&gt;
&lt;li&gt;Next patch/update, sugar will check &amp;quot;where sync_key=&amp;#39;AC0001&amp;#39;&amp;quot; and update it (it is indexed)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Integrate Upsert APIs
&lt;ul&gt;
&lt;li&gt;Sugar&amp;#39;s &amp;quot;update or insert&amp;quot; API based on sync_key&lt;/li&gt;
&lt;li&gt;Replaces commonly used check if exists, update or create (GET and POST or PUT)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_PATCH"&gt;Upsert by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_GET"&gt;Get by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_DELETE"&gt;Delete by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulerecord_idsync_key_field_namesync_key_field_value_PATCH"&gt;Set a sync on existing record (without sync_key)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_POST"&gt;Create relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_DELETE"&gt;Delete relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Bulk API
&lt;ul&gt;
&lt;li&gt;Endpoint that encapsulates multiple API calls into one single HTTP request&lt;/li&gt;
&lt;li&gt;Requests are executed synchronously (one after the other)&lt;/li&gt;
&lt;li&gt;Reducing network latency between calls&lt;/li&gt;
&lt;li&gt;Combined with Upsert provides the best performance&lt;/li&gt;
&lt;li&gt;Careful not to add too many requests to it&lt;/li&gt;
&lt;li&gt;Start small (5 to 10 requests) and increase until you reach it&amp;#39;s max capacity&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Polling and filtering time-based with Filter API
&lt;ul&gt;
&lt;li&gt;Integration gateway (or your external system) asks Sugar every X minutes&lt;/li&gt;
&lt;li&gt;Request Filter API using &lt;code&gt;max_num&lt;/code&gt; (max number of records), offset and fields&lt;/li&gt;
&lt;li&gt;Response will provide the data as well as &lt;code&gt;next_offset&lt;/code&gt; (offset can be seen as pagination)&lt;/li&gt;
&lt;li&gt;if &lt;code&gt;next_offset&lt;/code&gt; is -1, no more records to go through&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Initial Data Load into Sugar&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Use Bulk + Upsert to achieve data loads&lt;/li&gt;
&lt;li&gt;Millions&amp;nbsp;of records may take a little while to process, plan ahead (over the weekend)&lt;/li&gt;
&lt;li&gt;Use multi-thread processes to load (for example 20 threads sending 20 bulk upsert requests)&lt;/li&gt;
&lt;li&gt;Careful with&amp;nbsp;&lt;a href="https://support.sugarcrm.com/Resources/Sugar_Cloud_Policy_Guide/#Rate_Limits"&gt;Sugar Cloud rate limits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;It&amp;#39;s always a good idea to let Sugar Support know you&amp;#39;re data loading, they will be considerate.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Understanding PHP limitations
&lt;ul&gt;
&lt;li&gt;PHP allocates OS resources to process your request&lt;/li&gt;
&lt;li&gt;If you send too much data using bulk, you may run out of memory for that request&lt;/li&gt;
&lt;li&gt;Push to the limits but give some room for PHP to finish the request gracefully&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3 id="mcetoc_1f5uvkqns0"&gt;&lt;span style="font-size:inherit;"&gt;You&amp;#39;re up and running, but don&amp;#39;t stop now - this is just the beginning of your journey. Now it&amp;#39;s time to &lt;a href="/dev-club/dev-onboarding/w/documentation/686/customization-for-devs"&gt;Customizations&lt;/a&gt;.&lt;/span&gt;&lt;/h3&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Integrations for Devs</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs/revision/16</link><pubDate>Thu, 14 Jul 2022 15:41:24 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:df5ca10a-d211-4e03-9873-9d48feb7b645</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs#comments</comments><description>Revision 16 posted to Dev Tutorials by Rafael Fernandes on 7/14/2022 3:41:24 PM&lt;br /&gt;
&lt;p&gt;&lt;span style="background-color:#ff0000;font-size:150%;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="#register"&gt;&lt;img alt=" " src="/resized-image/__size/272x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.17.45-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#setup"&gt;&lt;img alt=" " src="/resized-image/__size/273x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.00-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#api"&gt;&lt;img alt=" " src="/resized-image/__size/273x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.20-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#learn"&gt;&lt;img alt=" " src="/resized-image/__size/272x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.19.03-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="setup"&gt;&lt;/a&gt;Integration Approaches&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;Sugar platform is extremely powerful and easy to integrate with. Determining the right approach for your use case scenario is the key to success.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/263x136/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.00-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Push/Pull from Sugar via REST API&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Recommended approach&lt;/li&gt;
&lt;li&gt;Developers have full control over integration&lt;/li&gt;
&lt;li&gt;Integration can be stopped and systems will continue to work&lt;/li&gt;
&lt;li&gt;Retry mechanism: Resume integrations at any time (bringing only delta changes through &amp;quot;last_udpdate_time&amp;quot; flags)&lt;/li&gt;
&lt;li&gt;Time delay from/to Sugar is minimum and bearable&lt;/li&gt;
&lt;li&gt;Sugar REST API offers everything you need, but can be extended&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Push to Sugar, Sugar pushes to external queue in realtime&lt;span&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;Uses Sugar Events to trigger through Logic Hooks&lt;/li&gt;
&lt;li&gt;Requires&amp;nbsp;Logic Hooks to be created and deployed&lt;/li&gt;
&lt;li&gt;Does not offer &amp;quot;retry mechanism&amp;quot;, if a logic hook fails to deliver to a queue or contact external system&lt;/li&gt;
&lt;li&gt;Synchronous in nature, requires a response from external system&lt;/li&gt;
&lt;li&gt;Needs to handle dependencies manually (contact can only be created after account)&lt;/li&gt;
&lt;li&gt;Good to have a middleware/queue in front of Sugar to receive those event triggers (not mandatory but would make it &amp;quot;asynchronous&amp;quot;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Realtime: Embed your app into Sugar&amp;nbsp;through &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/User_Interface/Dashlets/"&gt;Dashlets&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Simplest approach&lt;/li&gt;
&lt;li&gt;Often requires user-based authentication&lt;/li&gt;
&lt;li&gt;All load/traffic goes directly to your system,&amp;nbsp;careful with&amp;nbsp;bottlenecks&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="register"&gt;&lt;/a&gt;REST API Webservices&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Accessing your data when you want is good. &amp;nbsp;Accessing your data however you want is better. &lt;/span&gt;&lt;span&gt;When you decide to build an integration with Sugar, you&amp;rsquo;ll need an easy way to access and interact with the data stored in Sugar. The REST (&lt;/span&gt;&lt;span&gt;representational state transfer)&lt;/span&gt;&lt;span&gt;&amp;nbsp;API (application programming interface) is perfect for this.&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sugar REST API Overview
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;Fully RESTfull (GET, POST, PUT, DELETE)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;OAuth2 token based&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;All fields and modules are available through the API automatically&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Metadata API provides everything you need to know about your Sugar instance.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/271x140/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.17.45-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Topics
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/new-tutorial-intro-to-the-sugar-rest-api"&gt;Intro to the Sugar REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/how-sugar-rest-api-versioning-works"&gt;How Sugar REST API versioning works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/"&gt;RestAPI Developer Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/sugarcrm-cookbook---the-school-of-rest---part-1"&gt;School of REST blog series&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/"&gt;REST APIs Endpoints&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Extending_Endpoints/"&gt;How to add your own custom endpoints to the REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/API_Exceptions/"&gt;API Exceptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Best_Practices/"&gt;Best practices when integrating and migrating Sugar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="api"&gt;&lt;/a&gt;Common&amp;nbsp;APIs&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;It is important to understand our most commonly used APIs and their functions within Sugar. Your integration might need data within Sugar&amp;#39;s module structure that could potentially change over time, so you can use Metadata for it as well as CRUD onto Sugar.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/273x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.20-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Metadata
&lt;ul&gt;
&lt;li&gt;Endpoint with current system&amp;#39;s structure&lt;/li&gt;
&lt;li&gt;Modules, fields, relationships, layouts&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Use carefully, its payload can be MBs in size, cache as much as possible&lt;/li&gt;
&lt;li&gt;GET /metadata (use filters as much as possible)&lt;/li&gt;
&lt;li&gt;It does not retrieve lables for dropdowns, use language api to do so&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/3-tips-for-using-the-sugar-metadata-api"&gt;3 Tips for using the Sugar Metadata API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Language
&lt;ul&gt;
&lt;li&gt;Endpoint to retrieve labels&lt;/li&gt;
&lt;li&gt;Dropdown list values&lt;/li&gt;
&lt;li&gt;Any language specific content&lt;/li&gt;
&lt;li&gt;GET /lang/&amp;lt;language_code&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CRUD (Create, Read, Update, Delete) records
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_GET"&gt;Read&lt;/a&gt;: &lt;code&gt;GET /&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/module_POST"&gt;Create&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_PUT"&gt;Update&lt;/a&gt;: &lt;code&gt;PUT&amp;nbsp;&lt;span&gt;/&amp;lt;module&amp;gt;/:record&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_DELETE"&gt;Delete&lt;/a&gt;: &lt;code&gt;DELETE&amp;nbsp;/&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_POST"&gt;Filter&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;/filter&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;You can use &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_GET"&gt;GET&lt;/a&gt; as well&lt;/li&gt;
&lt;li&gt;POST solves the issue when a query is too long and hits HTTP limits&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_name_GET"&gt;Retrieve records related to another module&lt;/a&gt;:&amp;nbsp;&lt;code&gt;GET /&amp;lt;module&amp;gt;/:record/link/:link_name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_nameremote_id_POST"&gt;Creates a relationship to a pre-existing record:&lt;/a&gt;&lt;code&gt; POST /&amp;lt;module&amp;gt;/:record/link/:link_name/:remote_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="learn"&gt;&lt;/a&gt;Performance and Best Practices&lt;/h1&gt;
&lt;div class="row"&gt;
&lt;div class="col-xs-12 col-md-9"&gt;
&lt;p&gt;As you deep dive into Sugar APIs,&amp;nbsp;you will see how easy it is to integrate to pull and push data from and to Sugar and your systems, however, you must consider performance so your integration doesn&amp;#39;t become a bottleneck between those systems.&lt;/p&gt;
&lt;p&gt;You should consider the following guidelines when implementing your integrations:&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/272x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.19.03-PM.png" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Use Sugar&amp;#39;s sync_key
&lt;ul&gt;
&lt;li&gt;Sugar provides in every module a sync_key field&lt;/li&gt;
&lt;li&gt;sync_key is a unique identifier for that module that links back to your external system&amp;#39;s generated key&lt;/li&gt;
&lt;li&gt;For example, account ID from ERP is AC0001, set sync_key (pass as parameter in the POST) and sugar will create a record in account with sync_key=AC0001&lt;/li&gt;
&lt;li&gt;Next patch/update, sugar will check &amp;quot;where sync_key=&amp;#39;AC0001&amp;#39;&amp;quot; and update it (it is indexed)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Integrate Upsert APIs
&lt;ul&gt;
&lt;li&gt;Sugar&amp;#39;s &amp;quot;update or insert&amp;quot; API based on sync_key&lt;/li&gt;
&lt;li&gt;Replaces commonly used check if exists, update or create (GET and POST or PUT)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_PATCH"&gt;Upsert by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_GET"&gt;Get by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_DELETE"&gt;Delete by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulerecord_idsync_key_field_namesync_key_field_value_PATCH"&gt;Set a sync on existing record (without sync_key)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_POST"&gt;Create relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_DELETE"&gt;Delete relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Bulk API
&lt;ul&gt;
&lt;li&gt;Endpoint that encapsulates multiple API calls into one single HTTP request&lt;/li&gt;
&lt;li&gt;Requests are executed synchronously (one after the other)&lt;/li&gt;
&lt;li&gt;Reducing network latency between calls&lt;/li&gt;
&lt;li&gt;Combined with Upsert provides the best performance&lt;/li&gt;
&lt;li&gt;Careful not to add too many requests to it&lt;/li&gt;
&lt;li&gt;Start small (5 to 10 requests) and increase until you reach it&amp;#39;s max capacity&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Polling and filtering time-based with Filter API
&lt;ul&gt;
&lt;li&gt;Integration gateway (or your external system) asks Sugar every X minutes&lt;/li&gt;
&lt;li&gt;Request Filter API using &lt;code&gt;max_num&lt;/code&gt; (max number of records), offset and fields&lt;/li&gt;
&lt;li&gt;Response will provide the data as well as &lt;code&gt;next_offset&lt;/code&gt; (offset can be seen as pagination)&lt;/li&gt;
&lt;li&gt;if &lt;code&gt;next_offset&lt;/code&gt; is -1, no more records to go through&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Initial Data Load into Sugar&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Use Bulk + Upsert to achieve data loads&lt;/li&gt;
&lt;li&gt;Millions&amp;nbsp;of records may take a little while to process, plan ahead (over the weekend)&lt;/li&gt;
&lt;li&gt;Use multi-thread processes to load (for example 20 threads sending 20 bulk upsert requests)&lt;/li&gt;
&lt;li&gt;Careful with&amp;nbsp;&lt;a href="https://support.sugarcrm.com/Resources/Sugar_Cloud_Policy_Guide/#Rate_Limits"&gt;Sugar Cloud rate limits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;It&amp;#39;s always a good idea to let Sugar Support know you&amp;#39;re data loading, they will be considerate.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Understanding PHP limitations
&lt;ul&gt;
&lt;li&gt;PHP allocates OS resources to process your request&lt;/li&gt;
&lt;li&gt;If you send too much data using bulk, you may run out of memory for that request&lt;/li&gt;
&lt;li&gt;Push to the limits but give some room for PHP to finish the request gracefully&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3 id="mcetoc_1f5uvkqns0"&gt;&lt;span style="font-size:inherit;"&gt;You&amp;#39;re up and running, but don&amp;#39;t stop now - this is just the beginning of your journey. Now it&amp;#39;s time to &lt;a href="/dev-club/dev-onboarding/w/documentation/686/customization-for-devs"&gt;Customizations&lt;/a&gt;.&lt;/span&gt;&lt;/h3&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Integrations for Devs</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs/revision/15</link><pubDate>Thu, 14 Jul 2022 15:41:08 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:df5ca10a-d211-4e03-9873-9d48feb7b645</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs#comments</comments><description>Revision 15 posted to Dev Tutorials by Rafael Fernandes on 7/14/2022 3:41:08 PM&lt;br /&gt;
&lt;p&gt;&lt;span style="background-color:#ff0000;font-size:150%;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="#register"&gt;&lt;img alt=" " src="/resized-image/__size/272x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.17.45-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#setup"&gt;&lt;img alt=" " src="/resized-image/__size/273x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.00-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#api"&gt;&lt;img alt=" " src="/resized-image/__size/273x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.20-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#learn"&gt;&lt;img alt=" " src="/resized-image/__size/272x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.19.03-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="setup"&gt;&lt;/a&gt;Integration Approaches&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;Sugar platform is extremely powerful and easy to integrate with. Determining the right approach for your use case scenario is the key to success.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/263x136/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.00-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Push/Pull from Sugar via REST API&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Recommended approach&lt;/li&gt;
&lt;li&gt;Developers have full control over integration&lt;/li&gt;
&lt;li&gt;Integration can be stopped and systems will continue to work&lt;/li&gt;
&lt;li&gt;Retry mechanism: Resume integrations at any time (bringing only delta changes through &amp;quot;last_udpdate_time&amp;quot; flags)&lt;/li&gt;
&lt;li&gt;Time delay from/to Sugar is minimum and bearable&lt;/li&gt;
&lt;li&gt;Sugar REST API offers everything you need, but can be extended&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Push to Sugar, Sugar pushes to external queue in realtime&lt;span&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;Uses Sugar Events to trigger through Logic Hooks&lt;/li&gt;
&lt;li&gt;Requires&amp;nbsp;Logic Hooks to be created and deployed&lt;/li&gt;
&lt;li&gt;Does not offer &amp;quot;retry mechanism&amp;quot;, if a logic hook fails to deliver to a queue or contact external system&lt;/li&gt;
&lt;li&gt;Synchronous in nature, requires a response from external system&lt;/li&gt;
&lt;li&gt;Needs to handle dependencies manually (contact can only be created after account)&lt;/li&gt;
&lt;li&gt;Good to have a middleware/queue in front of Sugar to receive those event triggers (not mandatory but would make it &amp;quot;asynchronous&amp;quot;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Realtime: Embed your app into Sugar&amp;nbsp;through &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/User_Interface/Dashlets/"&gt;Dashlets&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Simplest approach&lt;/li&gt;
&lt;li&gt;Often requires user-based authentication&lt;/li&gt;
&lt;li&gt;All load/traffic goes directly to your system,&amp;nbsp;careful with&amp;nbsp;bottlenecks&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="register"&gt;&lt;/a&gt;Webservices&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Accessing your data when you want is good. &amp;nbsp;Accessing your data however you want is better. &lt;/span&gt;&lt;span&gt;When you decide to build an integration with Sugar, you&amp;rsquo;ll need an easy way to access and interact with the data stored in Sugar. The REST (&lt;/span&gt;&lt;span&gt;representational state transfer)&lt;/span&gt;&lt;span&gt;&amp;nbsp;API (application programming interface) is perfect for this.&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sugar REST API Overview
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;Fully RESTfull (GET, POST, PUT, DELETE)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;OAuth2 token based&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;All fields and modules are available through the API automatically&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Metadata API provides everything you need to know about your Sugar instance.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/271x140/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.17.45-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Topics
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/new-tutorial-intro-to-the-sugar-rest-api"&gt;Intro to the Sugar REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/how-sugar-rest-api-versioning-works"&gt;How Sugar REST API versioning works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/"&gt;RestAPI Developer Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/sugarcrm-cookbook---the-school-of-rest---part-1"&gt;School of REST blog series&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/"&gt;REST APIs Endpoints&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Extending_Endpoints/"&gt;How to add your own custom endpoints to the REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/API_Exceptions/"&gt;API Exceptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Best_Practices/"&gt;Best practices when integrating and migrating Sugar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="api"&gt;&lt;/a&gt;Common&amp;nbsp;APIs&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;It is important to understand our most commonly used APIs and their functions within Sugar. Your integration might need data within Sugar&amp;#39;s module structure that could potentially change over time, so you can use Metadata for it as well as CRUD onto Sugar.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/273x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.20-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Metadata
&lt;ul&gt;
&lt;li&gt;Endpoint with current system&amp;#39;s structure&lt;/li&gt;
&lt;li&gt;Modules, fields, relationships, layouts&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Use carefully, its payload can be MBs in size, cache as much as possible&lt;/li&gt;
&lt;li&gt;GET /metadata (use filters as much as possible)&lt;/li&gt;
&lt;li&gt;It does not retrieve lables for dropdowns, use language api to do so&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/3-tips-for-using-the-sugar-metadata-api"&gt;3 Tips for using the Sugar Metadata API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Language
&lt;ul&gt;
&lt;li&gt;Endpoint to retrieve labels&lt;/li&gt;
&lt;li&gt;Dropdown list values&lt;/li&gt;
&lt;li&gt;Any language specific content&lt;/li&gt;
&lt;li&gt;GET /lang/&amp;lt;language_code&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CRUD (Create, Read, Update, Delete) records
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_GET"&gt;Read&lt;/a&gt;: &lt;code&gt;GET /&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/module_POST"&gt;Create&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_PUT"&gt;Update&lt;/a&gt;: &lt;code&gt;PUT&amp;nbsp;&lt;span&gt;/&amp;lt;module&amp;gt;/:record&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_DELETE"&gt;Delete&lt;/a&gt;: &lt;code&gt;DELETE&amp;nbsp;/&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_POST"&gt;Filter&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;/filter&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;You can use &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_GET"&gt;GET&lt;/a&gt; as well&lt;/li&gt;
&lt;li&gt;POST solves the issue when a query is too long and hits HTTP limits&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_name_GET"&gt;Retrieve records related to another module&lt;/a&gt;:&amp;nbsp;&lt;code&gt;GET /&amp;lt;module&amp;gt;/:record/link/:link_name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_nameremote_id_POST"&gt;Creates a relationship to a pre-existing record:&lt;/a&gt;&lt;code&gt; POST /&amp;lt;module&amp;gt;/:record/link/:link_name/:remote_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="learn"&gt;&lt;/a&gt;Performance and Best Practices&lt;/h1&gt;
&lt;div class="row"&gt;
&lt;div class="col-xs-12 col-md-9"&gt;
&lt;p&gt;As you deep dive into Sugar APIs,&amp;nbsp;you will see how easy it is to integrate to pull and push data from and to Sugar and your systems, however, you must consider performance so your integration doesn&amp;#39;t become a bottleneck between those systems.&lt;/p&gt;
&lt;p&gt;You should consider the following guidelines when implementing your integrations:&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/272x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.19.03-PM.png" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Use Sugar&amp;#39;s sync_key
&lt;ul&gt;
&lt;li&gt;Sugar provides in every module a sync_key field&lt;/li&gt;
&lt;li&gt;sync_key is a unique identifier for that module that links back to your external system&amp;#39;s generated key&lt;/li&gt;
&lt;li&gt;For example, account ID from ERP is AC0001, set sync_key (pass as parameter in the POST) and sugar will create a record in account with sync_key=AC0001&lt;/li&gt;
&lt;li&gt;Next patch/update, sugar will check &amp;quot;where sync_key=&amp;#39;AC0001&amp;#39;&amp;quot; and update it (it is indexed)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Integrate Upsert APIs
&lt;ul&gt;
&lt;li&gt;Sugar&amp;#39;s &amp;quot;update or insert&amp;quot; API based on sync_key&lt;/li&gt;
&lt;li&gt;Replaces commonly used check if exists, update or create (GET and POST or PUT)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_PATCH"&gt;Upsert by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_GET"&gt;Get by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_DELETE"&gt;Delete by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulerecord_idsync_key_field_namesync_key_field_value_PATCH"&gt;Set a sync on existing record (without sync_key)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_POST"&gt;Create relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_DELETE"&gt;Delete relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Bulk API
&lt;ul&gt;
&lt;li&gt;Endpoint that encapsulates multiple API calls into one single HTTP request&lt;/li&gt;
&lt;li&gt;Requests are executed synchronously (one after the other)&lt;/li&gt;
&lt;li&gt;Reducing network latency between calls&lt;/li&gt;
&lt;li&gt;Combined with Upsert provides the best performance&lt;/li&gt;
&lt;li&gt;Careful not to add too many requests to it&lt;/li&gt;
&lt;li&gt;Start small (5 to 10 requests) and increase until you reach it&amp;#39;s max capacity&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Polling and filtering time-based with Filter API
&lt;ul&gt;
&lt;li&gt;Integration gateway (or your external system) asks Sugar every X minutes&lt;/li&gt;
&lt;li&gt;Request Filter API using &lt;code&gt;max_num&lt;/code&gt; (max number of records), offset and fields&lt;/li&gt;
&lt;li&gt;Response will provide the data as well as &lt;code&gt;next_offset&lt;/code&gt; (offset can be seen as pagination)&lt;/li&gt;
&lt;li&gt;if &lt;code&gt;next_offset&lt;/code&gt; is -1, no more records to go through&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Initial Data Load into Sugar&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Use Bulk + Upsert to achieve data loads&lt;/li&gt;
&lt;li&gt;Millions&amp;nbsp;of records may take a little while to process, plan ahead (over the weekend)&lt;/li&gt;
&lt;li&gt;Use multi-thread processes to load (for example 20 threads sending 20 bulk upsert requests)&lt;/li&gt;
&lt;li&gt;Careful with&amp;nbsp;&lt;a href="https://support.sugarcrm.com/Resources/Sugar_Cloud_Policy_Guide/#Rate_Limits"&gt;Sugar Cloud rate limits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;It&amp;#39;s always a good idea to let Sugar Support know you&amp;#39;re data loading, they will be considerate.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Understanding PHP limitations
&lt;ul&gt;
&lt;li&gt;PHP allocates OS resources to process your request&lt;/li&gt;
&lt;li&gt;If you send too much data using bulk, you may run out of memory for that request&lt;/li&gt;
&lt;li&gt;Push to the limits but give some room for PHP to finish the request gracefully&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3 id="mcetoc_1f5uvkqns0"&gt;&lt;span style="font-size:inherit;"&gt;You&amp;#39;re up and running, but don&amp;#39;t stop now - this is just the beginning of your journey. Now it&amp;#39;s time to &lt;a href="/dev-club/dev-onboarding/w/documentation/686/customization-for-devs"&gt;Customizations&lt;/a&gt;.&lt;/span&gt;&lt;/h3&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Integrations for Devs</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs/revision/14</link><pubDate>Thu, 14 Jul 2022 15:40:11 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:df5ca10a-d211-4e03-9873-9d48feb7b645</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs#comments</comments><description>Revision 14 posted to Dev Tutorials by Rafael Fernandes on 7/14/2022 3:40:11 PM&lt;br /&gt;
&lt;p&gt;&lt;span style="background-color:#ff0000;font-size:150%;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="#register"&gt;&lt;img alt=" " src="/resized-image/__size/272x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.17.45-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#setup"&gt;&lt;img alt=" " src="/resized-image/__size/273x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.00-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#api"&gt;&lt;img alt=" " src="/resized-image/__size/273x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.20-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#learn"&gt;&lt;img alt=" " src="/resized-image/__size/272x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.19.03-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="setup"&gt;&lt;/a&gt;Integration Approaches&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;Sugar platform is extremely powerful and easy to integrate with. Determining the right approach for your use case scenario is the key to success.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/263x136/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.00-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Push/Pull from Sugar via REST API&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Recommended approach&lt;/li&gt;
&lt;li&gt;Developers have full control over integration&lt;/li&gt;
&lt;li&gt;Integration can be stopped and systems will continue to work&lt;/li&gt;
&lt;li&gt;Retry mechanism: Resume integrations at any time (bringing only delta changes through &amp;quot;last_udpdate_time&amp;quot; flags)&lt;/li&gt;
&lt;li&gt;Time delay from/to Sugar is minimum and bearable&lt;/li&gt;
&lt;li&gt;Sugar REST API offers everything you need, but can be extended&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Push to Sugar, Sugar pushes to external queue in realtime&lt;span&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;Uses Sugar Events to trigger through Logic Hooks&lt;/li&gt;
&lt;li&gt;Requires&amp;nbsp;Logic Hooks to be created and deployed&lt;/li&gt;
&lt;li&gt;Does not offer &amp;quot;retry mechanism&amp;quot;, if a logic hook fails to deliver to a queue or contact external system&lt;/li&gt;
&lt;li&gt;Synchronous in nature, requires a response from external system&lt;/li&gt;
&lt;li&gt;Needs to handle dependencies manually (contact can only be created after account)&lt;/li&gt;
&lt;li&gt;Good to have a middleware/queue in front of Sugar to receive those event triggers (not mandatory but would make it &amp;quot;asynchronous&amp;quot;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Realtime: Embed your app into Sugar&amp;nbsp;through &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/User_Interface/Dashlets/"&gt;Dashlets&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Simplest approach&lt;/li&gt;
&lt;li&gt;Often requires user-based authentication&lt;/li&gt;
&lt;li&gt;All load/traffic goes directly to your system,&amp;nbsp;careful with&amp;nbsp;bottlenecks&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="register"&gt;&lt;/a&gt;Integrating with Sugar&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Accessing your data when you want is good. &amp;nbsp;Accessing your data however you want is better. &lt;/span&gt;&lt;span&gt;When you decide to build an integration with Sugar, you&amp;rsquo;ll need an easy way to access and interact with the data stored in Sugar. The REST (&lt;/span&gt;&lt;span&gt;representational state transfer)&lt;/span&gt;&lt;span&gt;&amp;nbsp;API (application programming interface) is perfect for this.&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sugar REST API Overview
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;Fully RESTfull (GET, POST, PUT, DELETE)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;OAuth2 token based&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;All fields and modules are available through the API automatically&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Metadata API provides everything you need to know about your Sugar instance.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/271x140/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.17.45-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Topics
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/new-tutorial-intro-to-the-sugar-rest-api"&gt;Intro to the Sugar REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/how-sugar-rest-api-versioning-works"&gt;How Sugar REST API versioning works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/"&gt;RestAPI Developer Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/sugarcrm-cookbook---the-school-of-rest---part-1"&gt;School of REST blog series&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/"&gt;REST APIs Endpoints&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Extending_Endpoints/"&gt;How to add your own custom endpoints to the REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/API_Exceptions/"&gt;API Exceptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Best_Practices/"&gt;Best practices when integrating and migrating Sugar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="api"&gt;&lt;/a&gt;Common&amp;nbsp;APIs&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;It is important to understand our most commonly used APIs and their functions within Sugar. Your integration might need data within Sugar&amp;#39;s module structure that could potentially change over time, so you can use Metadata for it as well as CRUD onto Sugar.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/273x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.20-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Metadata
&lt;ul&gt;
&lt;li&gt;Endpoint with current system&amp;#39;s structure&lt;/li&gt;
&lt;li&gt;Modules, fields, relationships, layouts&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Use carefully, its payload can be MBs in size, cache as much as possible&lt;/li&gt;
&lt;li&gt;GET /metadata (use filters as much as possible)&lt;/li&gt;
&lt;li&gt;It does not retrieve lables for dropdowns, use language api to do so&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/3-tips-for-using-the-sugar-metadata-api"&gt;3 Tips for using the Sugar Metadata API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Language
&lt;ul&gt;
&lt;li&gt;Endpoint to retrieve labels&lt;/li&gt;
&lt;li&gt;Dropdown list values&lt;/li&gt;
&lt;li&gt;Any language specific content&lt;/li&gt;
&lt;li&gt;GET /lang/&amp;lt;language_code&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CRUD (Create, Read, Update, Delete) records
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_GET"&gt;Read&lt;/a&gt;: &lt;code&gt;GET /&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/module_POST"&gt;Create&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_PUT"&gt;Update&lt;/a&gt;: &lt;code&gt;PUT&amp;nbsp;&lt;span&gt;/&amp;lt;module&amp;gt;/:record&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_DELETE"&gt;Delete&lt;/a&gt;: &lt;code&gt;DELETE&amp;nbsp;/&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_POST"&gt;Filter&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;/filter&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;You can use &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_GET"&gt;GET&lt;/a&gt; as well&lt;/li&gt;
&lt;li&gt;POST solves the issue when a query is too long and hits HTTP limits&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_name_GET"&gt;Retrieve records related to another module&lt;/a&gt;:&amp;nbsp;&lt;code&gt;GET /&amp;lt;module&amp;gt;/:record/link/:link_name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_nameremote_id_POST"&gt;Creates a relationship to a pre-existing record:&lt;/a&gt;&lt;code&gt; POST /&amp;lt;module&amp;gt;/:record/link/:link_name/:remote_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="learn"&gt;&lt;/a&gt;Performance and Best Practices&lt;/h1&gt;
&lt;div class="row"&gt;
&lt;div class="col-xs-12 col-md-9"&gt;
&lt;p&gt;As you deep dive into Sugar APIs,&amp;nbsp;you will see how easy it is to integrate to pull and push data from and to Sugar and your systems, however, you must consider performance so your integration doesn&amp;#39;t become a bottleneck between those systems.&lt;/p&gt;
&lt;p&gt;You should consider the following guidelines when implementing your integrations:&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/272x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.19.03-PM.png" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Use Sugar&amp;#39;s sync_key
&lt;ul&gt;
&lt;li&gt;Sugar provides in every module a sync_key field&lt;/li&gt;
&lt;li&gt;sync_key is a unique identifier for that module that links back to your external system&amp;#39;s generated key&lt;/li&gt;
&lt;li&gt;For example, account ID from ERP is AC0001, set sync_key (pass as parameter in the POST) and sugar will create a record in account with sync_key=AC0001&lt;/li&gt;
&lt;li&gt;Next patch/update, sugar will check &amp;quot;where sync_key=&amp;#39;AC0001&amp;#39;&amp;quot; and update it (it is indexed)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Integrate Upsert APIs
&lt;ul&gt;
&lt;li&gt;Sugar&amp;#39;s &amp;quot;update or insert&amp;quot; API based on sync_key&lt;/li&gt;
&lt;li&gt;Replaces commonly used check if exists, update or create (GET and POST or PUT)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_PATCH"&gt;Upsert by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_GET"&gt;Get by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_DELETE"&gt;Delete by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulerecord_idsync_key_field_namesync_key_field_value_PATCH"&gt;Set a sync on existing record (without sync_key)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_POST"&gt;Create relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_DELETE"&gt;Delete relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Bulk API
&lt;ul&gt;
&lt;li&gt;Endpoint that encapsulates multiple API calls into one single HTTP request&lt;/li&gt;
&lt;li&gt;Requests are executed synchronously (one after the other)&lt;/li&gt;
&lt;li&gt;Reducing network latency between calls&lt;/li&gt;
&lt;li&gt;Combined with Upsert provides the best performance&lt;/li&gt;
&lt;li&gt;Careful not to add too many requests to it&lt;/li&gt;
&lt;li&gt;Start small (5 to 10 requests) and increase until you reach it&amp;#39;s max capacity&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Polling and filtering time-based with Filter API
&lt;ul&gt;
&lt;li&gt;Integration gateway (or your external system) asks Sugar every X minutes&lt;/li&gt;
&lt;li&gt;Request Filter API using &lt;code&gt;max_num&lt;/code&gt; (max number of records), offset and fields&lt;/li&gt;
&lt;li&gt;Response will provide the data as well as &lt;code&gt;next_offset&lt;/code&gt; (offset can be seen as pagination)&lt;/li&gt;
&lt;li&gt;if &lt;code&gt;next_offset&lt;/code&gt; is -1, no more records to go through&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Initial Data Load into Sugar&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Use Bulk + Upsert to achieve data loads&lt;/li&gt;
&lt;li&gt;Millions&amp;nbsp;of records may take a little while to process, plan ahead (over the weekend)&lt;/li&gt;
&lt;li&gt;Use multi-thread processes to load (for example 20 threads sending 20 bulk upsert requests)&lt;/li&gt;
&lt;li&gt;Careful with&amp;nbsp;&lt;a href="https://support.sugarcrm.com/Resources/Sugar_Cloud_Policy_Guide/#Rate_Limits"&gt;Sugar Cloud rate limits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;It&amp;#39;s always a good idea to let Sugar Support know you&amp;#39;re data loading, they will be considerate.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Understanding PHP limitations
&lt;ul&gt;
&lt;li&gt;PHP allocates OS resources to process your request&lt;/li&gt;
&lt;li&gt;If you send too much data using bulk, you may run out of memory for that request&lt;/li&gt;
&lt;li&gt;Push to the limits but give some room for PHP to finish the request gracefully&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3 id="mcetoc_1f5uvkqns0"&gt;&lt;span style="font-size:inherit;"&gt;You&amp;#39;re up and running, but don&amp;#39;t stop now - this is just the beginning of your journey. Now it&amp;#39;s time to &lt;a href="/dev-club/dev-onboarding/w/documentation/686/customization-for-devs"&gt;Customizations&lt;/a&gt;.&lt;/span&gt;&lt;/h3&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Integrations for Devs</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs/revision/13</link><pubDate>Thu, 14 Jul 2022 15:18:41 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:df5ca10a-d211-4e03-9873-9d48feb7b645</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs#comments</comments><description>Revision 13 posted to Dev Tutorials by Rafael Fernandes on 7/14/2022 3:18:41 PM&lt;br /&gt;
&lt;p&gt;&lt;span style="background-color:#ff0000;font-size:150%;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="#register"&gt;&lt;img alt=" " src="/resized-image/__size/272x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.17.45-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#setup"&gt;&lt;img alt=" " src="/resized-image/__size/273x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.00-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#api"&gt;&lt;img alt=" " src="/resized-image/__size/273x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.20-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#learn"&gt;&lt;img alt=" " src="/resized-image/__size/272x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.19.03-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="setup"&gt;&lt;/a&gt;Integration Approaches&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;Sugar platform is extremely powerful and easy to integrate with. Determining the right approach for your use case scenario is the key to success.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/263x136/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.00-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Push/Pull from Sugar via REST API&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Recommended approach&lt;/li&gt;
&lt;li&gt;Developers have full control over integration&lt;/li&gt;
&lt;li&gt;Integration can be stopped and systems will continue to work&lt;/li&gt;
&lt;li&gt;Retry mechanism: Resume integrations at any time (bringing only delta changes through &amp;quot;last_udpdate_time&amp;quot; flags)&lt;/li&gt;
&lt;li&gt;Time delay from/to Sugar is minimum and bearable&lt;/li&gt;
&lt;li&gt;Sugar REST API offers everything you need, but can be extended&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Push to Sugar, Sugar pushes to external queue in realtime&lt;span&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;Uses Sugar Events to trigger through Logic Hooks&lt;/li&gt;
&lt;li&gt;Requires&amp;nbsp;Logic Hooks to be created and deployed&lt;/li&gt;
&lt;li&gt;Does not offer &amp;quot;retry mechanism&amp;quot;, if a logic hook fails to deliver to a queue or contact external system&lt;/li&gt;
&lt;li&gt;Synchronous in nature, requires a response from external system&lt;/li&gt;
&lt;li&gt;Needs to handle dependencies manually (contact can only be created after account)&lt;/li&gt;
&lt;li&gt;Good to have a middleware/queue in front of Sugar to receive those event triggers (not mandatory but would make it &amp;quot;asynchronous&amp;quot;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Realtime: Embed your app into Sugar&amp;nbsp;through &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/User_Interface/Dashlets/"&gt;Dashlets&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Simplest approach&lt;/li&gt;
&lt;li&gt;Often requires user-based authentication&lt;/li&gt;
&lt;li&gt;All load/traffic goes directly to your system,&amp;nbsp;careful with&amp;nbsp;bottlenecks&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="register"&gt;&lt;/a&gt;Integrating with Sugar&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Accessing your data when you want is good. &amp;nbsp;Accessing your data however you want is better. &lt;/span&gt;&lt;span&gt;When you decide to build an integration with Sugar, you&amp;rsquo;ll need an easy way to access and interact with the data stored in Sugar. The REST (&lt;/span&gt;&lt;span&gt;representational state transfer)&lt;/span&gt;&lt;span&gt;&amp;nbsp;API (application programming interface) is perfect for this.&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sugar REST API Overview
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;Fully RESTfull (GET, POST, PUT, DELETE)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;OAuth2 token based&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;All fields and modules are available through the API automatically&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Metadata API provides everything you need to know about your Sugar instance.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/271x140/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.17.45-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Topics
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/new-tutorial-intro-to-the-sugar-rest-api"&gt;Intro to the Sugar REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/how-sugar-rest-api-versioning-works"&gt;How Sugar REST API versioning works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/"&gt;RestAPI Developer Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/sugarcrm-cookbook---the-school-of-rest---part-1"&gt;School of REST blog series&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/"&gt;REST APIs Endpoints&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Extending_Endpoints/"&gt;How to add your own custom endpoints to the REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/API_Exceptions/"&gt;API Exceptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Best_Practices/"&gt;Best practices when integrating and migrating Sugar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="api"&gt;&lt;/a&gt;Common&amp;nbsp;APIs&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;It is important to understand our most commonly used APIs and their functions within Sugar. Your integration might need data within Sugar&amp;#39;s module structure that could potentially change over time, so you can use Metadata for it as well as CRUD onto Sugar.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/273x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.20-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Metadata
&lt;ul&gt;
&lt;li&gt;Endpoint with current system&amp;#39;s structure&lt;/li&gt;
&lt;li&gt;Modules, fields, relationships, layouts&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Use carefully, its payload can be MBs in size, cache as much as possible&lt;/li&gt;
&lt;li&gt;GET /metadata (use filters as much as possible)&lt;/li&gt;
&lt;li&gt;It does not retrieve lables for dropdowns, use language api to do so&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/3-tips-for-using-the-sugar-metadata-api"&gt;3 Tips for using the Sugar Metadata API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Language
&lt;ul&gt;
&lt;li&gt;Endpoint to retrieve labels&lt;/li&gt;
&lt;li&gt;Dropdown list values&lt;/li&gt;
&lt;li&gt;Any language specific content&lt;/li&gt;
&lt;li&gt;GET /lang/&amp;lt;language_code&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CRUD (Create, Read, Update, Delete) records
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_GET"&gt;Read&lt;/a&gt;: &lt;code&gt;GET /&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/module_POST"&gt;Create&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_PUT"&gt;Update&lt;/a&gt;: &lt;code&gt;PUT&amp;nbsp;&lt;span&gt;/&amp;lt;module&amp;gt;/:record&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_DELETE"&gt;Delete&lt;/a&gt;: &lt;code&gt;DELETE&amp;nbsp;/&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_POST"&gt;Filter&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;/filter&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;You can use &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_GET"&gt;GET&lt;/a&gt; as well&lt;/li&gt;
&lt;li&gt;POST solves the issue when a query is too long and hits HTTP limits&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_name_GET"&gt;Retrieve records related to another module&lt;/a&gt;:&amp;nbsp;&lt;code&gt;GET /&amp;lt;module&amp;gt;/:record/link/:link_name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_nameremote_id_POST"&gt;Creates a relationship to a pre-existing record:&lt;/a&gt;&lt;code&gt; POST /&amp;lt;module&amp;gt;/:record/link/:link_name/:remote_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="learn"&gt;&lt;/a&gt;Performance and Best Practices&lt;/h1&gt;
&lt;div class="row"&gt;
&lt;div class="col-xs-12 col-md-9"&gt;
&lt;p&gt;As you deep dive into Sugar APIs,&amp;nbsp;you will see how easy it is to integrate to pull and push data from and to Sugar and your systems, however, you must consider performance so your integration doesn&amp;#39;t become a bottleneck between those systems.&lt;/p&gt;
&lt;p&gt;You should consider the following guidelines when implementing your integrations:&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/272x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.19.03-PM.png" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Use Sugar&amp;#39;s sync_key
&lt;ul&gt;
&lt;li&gt;Sugar provides in every module a sync_key field&lt;/li&gt;
&lt;li&gt;sync_key is a unique identifier for that module that links back to your external system&amp;#39;s generated key&lt;/li&gt;
&lt;li&gt;For example, account ID from ERP is AC0001, set sync_key (pass as parameter in the POST) and sugar will create a record in account with sync_key=AC0001&lt;/li&gt;
&lt;li&gt;Next patch/update, sugar will check &amp;quot;where sync_key=&amp;#39;AC0001&amp;#39;&amp;quot; and update it (it is indexed)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Integrate Upsert APIs
&lt;ul&gt;
&lt;li&gt;Sugar&amp;#39;s &amp;quot;update or insert&amp;quot; API based on sync_key&lt;/li&gt;
&lt;li&gt;Replaces commonly used check if exists, update or create (GET and POST or PUT)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_PATCH"&gt;Upsert by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_GET"&gt;Get by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulesync_key_field_namesync_key_field_value_DELETE"&gt;Delete by sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulerecord_idsync_key_field_namesync_key_field_value_PATCH"&gt;Set a sync on existing record (without sync_key)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_POST"&gt;Create relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/Integratemodulelhs_sync_key_field_namelhs_sync_key_field_valuelinklink_namerhs_sync_key_field_namerhs_sync_key_field_value_DELETE"&gt;Delete relationship based on sync_key&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Bulk API
&lt;ul&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Polling and filtering time-based with Filter API
&lt;ul&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Initial Data Load into Sugar&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Basic knowledge of process design is required.&lt;/li&gt;
&lt;li&gt;Basic knowledge of process standards such as BPMN is preferred. BPMN is a flowchart-based notation used to define business processes within an organization.&lt;/li&gt;
&lt;li&gt;You should know which business processes you want to automate in Sugar.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/SugarBPM/Business_Process_Automation_via_SugarBPM/"&gt;Introduction to Business Process Automation via SugarBPM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/SugarBPM/Getting_Started_With_SugarBPM_for_Sugar_Serve/"&gt;Getting Started With SugarBPM for Sugar Serve&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/SugarBPM/Using_SugarBPM_to_Notify_a_Team_or_User_on_Record_Creation/"&gt;Using SugarBPM to Notify a Team or User on Record Creation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/SugarBPM/Understanding_Email_Direction_in_Process_Definitions/"&gt;Understanding Email Direction in Process Definitions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/SugarBPM/Understanding_Round_Robin_Activities_vs_Round_Robin_Actions/"&gt;Understanding Round Robin Activities vs. Round Robin Actions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/h1&gt;
&lt;h3 id="mcetoc_1f5uvkqns0"&gt;&lt;span style="font-size:inherit;"&gt;You&amp;#39;re up and running, but don&amp;#39;t stop now - this is just the beginning of your journey. Now it&amp;#39;s time to &lt;a href="/dev-club/dev-onboarding/w/documentation/686/customization-for-devs"&gt;Customizations&lt;/a&gt;.&lt;/span&gt;&lt;/h3&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Integrations for Devs</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs/revision/12</link><pubDate>Thu, 14 Jul 2022 15:07:30 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:df5ca10a-d211-4e03-9873-9d48feb7b645</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs#comments</comments><description>Revision 12 posted to Dev Tutorials by Rafael Fernandes on 7/14/2022 3:07:30 PM&lt;br /&gt;
&lt;p&gt;&lt;span style="background-color:#ff0000;font-size:150%;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="#register"&gt;&lt;img alt=" " src="/resized-image/__size/272x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.17.45-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#setup"&gt;&lt;img alt=" " src="/resized-image/__size/273x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.00-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#api"&gt;&lt;img alt=" " src="/resized-image/__size/273x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.20-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#learn"&gt;&lt;img alt=" " src="/resized-image/__size/272x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.19.03-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="setup"&gt;&lt;/a&gt;Integration Approaches&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;Sugar platform is extremely powerful and easy to integrate with. Determining the right approach for your use case scenario is the key to success.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/263x136/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.00-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Push/Pull from Sugar via REST API&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Recommended approach&lt;/li&gt;
&lt;li&gt;Developers have full control over integration&lt;/li&gt;
&lt;li&gt;Integration can be stopped and systems will continue to work&lt;/li&gt;
&lt;li&gt;Retry mechanism: Resume integrations at any time (bringing only delta changes through &amp;quot;last_udpdate_time&amp;quot; flags)&lt;/li&gt;
&lt;li&gt;Time delay from/to Sugar is minimum and bearable&lt;/li&gt;
&lt;li&gt;Sugar REST API offers everything you need, but can be extended&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Push to Sugar, Sugar pushes to external queue in realtime&lt;span&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;Uses Sugar Events to trigger through Logic Hooks&lt;/li&gt;
&lt;li&gt;Requires&amp;nbsp;Logic Hooks to be created and deployed&lt;/li&gt;
&lt;li&gt;Does not offer &amp;quot;retry mechanism&amp;quot;, if a logic hook fails to deliver to a queue or contact external system&lt;/li&gt;
&lt;li&gt;Synchronous in nature, requires a response from external system&lt;/li&gt;
&lt;li&gt;Needs to handle dependencies manually (contact can only be created after account)&lt;/li&gt;
&lt;li&gt;Good to have a middleware/queue in front of Sugar to receive those event triggers (not mandatory but would make it &amp;quot;asynchronous&amp;quot;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Realtime: Embed your app into Sugar&amp;nbsp;through &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/User_Interface/Dashlets/"&gt;Dashlets&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Simplest approach&lt;/li&gt;
&lt;li&gt;Often requires user-based authentication&lt;/li&gt;
&lt;li&gt;All load/traffic goes directly to your system,&amp;nbsp;careful with&amp;nbsp;bottlenecks&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="register"&gt;&lt;/a&gt;Integrating with Sugar&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Accessing your data when you want is good. &amp;nbsp;Accessing your data however you want is better. &lt;/span&gt;&lt;span&gt;When you decide to build an integration with Sugar, you&amp;rsquo;ll need an easy way to access and interact with the data stored in Sugar. The REST (&lt;/span&gt;&lt;span&gt;representational state transfer)&lt;/span&gt;&lt;span&gt;&amp;nbsp;API (application programming interface) is perfect for this.&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sugar REST API Overview
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;Fully RESTfull (GET, POST, PUT, DELETE)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;OAuth2 token based&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;All fields and modules are available through the API automatically&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Metadata API provides everything you need to know about your Sugar instance.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/271x140/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.17.45-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Topics
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/new-tutorial-intro-to-the-sugar-rest-api"&gt;Intro to the Sugar REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/how-sugar-rest-api-versioning-works"&gt;How Sugar REST API versioning works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/"&gt;RestAPI Developer Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/sugarcrm-cookbook---the-school-of-rest---part-1"&gt;School of REST blog series&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/"&gt;REST APIs Endpoints&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Extending_Endpoints/"&gt;How to add your own custom endpoints to the REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/API_Exceptions/"&gt;API Exceptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Best_Practices/"&gt;Best practices when integrating and migrating Sugar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="api"&gt;&lt;/a&gt;Common&amp;nbsp;APIs&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;It is important to understand our most commonly used APIs and their functions within Sugar. Your integration might need data within Sugar&amp;#39;s module structure that could potentially change over time, so you can use Metadata for it as well as CRUD onto Sugar.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/273x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.20-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Metadata
&lt;ul&gt;
&lt;li&gt;Endpoint with current system&amp;#39;s structure&lt;/li&gt;
&lt;li&gt;Modules, fields, relationships, layouts&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Use carefully, its payload can be MBs in size, cache as much as possible&lt;/li&gt;
&lt;li&gt;GET /metadata (use filters as much as possible)&lt;/li&gt;
&lt;li&gt;It does not retrieve lables for dropdowns, use language api to do so&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/3-tips-for-using-the-sugar-metadata-api"&gt;3 Tips for using the Sugar Metadata API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Language
&lt;ul&gt;
&lt;li&gt;Endpoint to retrieve labels&lt;/li&gt;
&lt;li&gt;Dropdown list values&lt;/li&gt;
&lt;li&gt;Any language specific content&lt;/li&gt;
&lt;li&gt;GET /lang/&amp;lt;language_code&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CRUD (Create, Read, Update, Delete) records
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_GET"&gt;Read&lt;/a&gt;: &lt;code&gt;GET /&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/module_POST"&gt;Create&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_PUT"&gt;Update&lt;/a&gt;: &lt;code&gt;PUT&amp;nbsp;&lt;span&gt;/&amp;lt;module&amp;gt;/:record&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_DELETE"&gt;Delete&lt;/a&gt;: &lt;code&gt;DELETE&amp;nbsp;/&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_POST"&gt;Filter&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;/filter&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;You can use &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_GET"&gt;GET&lt;/a&gt; as well&lt;/li&gt;
&lt;li&gt;POST solves the issue when a query is too long and hits HTTP limits&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_name_GET"&gt;Retrieve records related to another module&lt;/a&gt;:&amp;nbsp;&lt;code&gt;GET /&amp;lt;module&amp;gt;/:record/link/:link_name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_nameremote_id_POST"&gt;Creates a relationship to a pre-existing record:&lt;/a&gt;&lt;code&gt; POST /&amp;lt;module&amp;gt;/:record/link/:link_name/:remote_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="learn"&gt;&lt;/a&gt;Performance and Best Practices&lt;/h1&gt;
&lt;div class="row"&gt;
&lt;div class="col-xs-12 col-md-9"&gt;
&lt;p&gt;As you deep dive into Sugar APIs,&amp;nbsp;you will see how easy it is to integrate to pull and push data from and to Sugar and your systems, however, you must consider performance so your integration doesn&amp;#39;t become a bottleneck between those systems.&lt;/p&gt;
&lt;p&gt;You should consider the following guidelines when implementing your integrations:&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/272x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.19.03-PM.png" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Use Sugar&amp;#39;s sync_key
&lt;ul&gt;
&lt;li&gt;Sugar provides in every module a sync_key field&lt;/li&gt;
&lt;li&gt;sync_key is a unique identifier for that module that links back to your external system&amp;#39;s generated key&lt;/li&gt;
&lt;li&gt;For example, account ID from ERP is AC0001, set sync_key (pass as parameter in the POST) and sugar will create a record in account with sync_key=AC0001&lt;/li&gt;
&lt;li&gt;Next patch/update, sugar will check &amp;quot;where sync_key=&amp;#39;AC0001&amp;#39;&amp;quot; and update it (it is indexed)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Integrate Upsert APIs
&lt;ul&gt;
&lt;li&gt;Sugar&amp;#39;s &amp;quot;update or insert&amp;quot; API based on sync_key&lt;/li&gt;
&lt;li&gt;Replaces common&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use Sugar Bulk API
&lt;ul&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Polling and filtering time-based with Filter API
&lt;ul&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Initial Data Load into Sugar&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Basic knowledge of process design is required.&lt;/li&gt;
&lt;li&gt;Basic knowledge of process standards such as BPMN is preferred. BPMN is a flowchart-based notation used to define business processes within an organization.&lt;/li&gt;
&lt;li&gt;You should know which business processes you want to automate in Sugar.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/SugarBPM/Business_Process_Automation_via_SugarBPM/"&gt;Introduction to Business Process Automation via SugarBPM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/SugarBPM/Getting_Started_With_SugarBPM_for_Sugar_Serve/"&gt;Getting Started With SugarBPM for Sugar Serve&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/SugarBPM/Using_SugarBPM_to_Notify_a_Team_or_User_on_Record_Creation/"&gt;Using SugarBPM to Notify a Team or User on Record Creation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/SugarBPM/Understanding_Email_Direction_in_Process_Definitions/"&gt;Understanding Email Direction in Process Definitions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/SugarBPM/Understanding_Round_Robin_Activities_vs_Round_Robin_Actions/"&gt;Understanding Round Robin Activities vs. Round Robin Actions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/h1&gt;
&lt;h3 id="mcetoc_1f5uvkqns0"&gt;&lt;span style="font-size:inherit;"&gt;You&amp;#39;re up and running, but don&amp;#39;t stop now - this is just the beginning of your journey. Now it&amp;#39;s time to &lt;a href="/dev-club/dev-onboarding/w/documentation/686/customization-for-devs"&gt;Customizations&lt;/a&gt;.&lt;/span&gt;&lt;/h3&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Integrations for Devs</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs/revision/11</link><pubDate>Thu, 14 Jul 2022 13:53:10 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:df5ca10a-d211-4e03-9873-9d48feb7b645</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs#comments</comments><description>Revision 11 posted to Dev Tutorials by Rafael Fernandes on 7/14/2022 1:53:10 PM&lt;br /&gt;
&lt;p&gt;&lt;span style="background-color:#ff0000;font-size:150%;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="#register"&gt;&lt;img alt=" " src="/resized-image/__size/272x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.17.45-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#setup"&gt;&lt;img alt=" " src="/resized-image/__size/273x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.00-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#api"&gt;&lt;img alt=" " src="/resized-image/__size/273x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.20-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#learn"&gt;&lt;img alt=" " src="/resized-image/__size/272x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.19.03-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="setup"&gt;&lt;/a&gt;Integration Approaches&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;Sugar platform is extremely powerful and easy to integrate with. Determining the right approach for your use case scenario is the key to success.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/263x136/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.00-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Push/Pull from Sugar via REST API&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Recommended approach&lt;/li&gt;
&lt;li&gt;Developers have full control over integration&lt;/li&gt;
&lt;li&gt;Integration can be stopped and systems will continue to work&lt;/li&gt;
&lt;li&gt;Retry mechanism: Resume integrations at any time (bringing only delta changes through &amp;quot;last_udpdate_time&amp;quot; flags)&lt;/li&gt;
&lt;li&gt;Time delay from/to Sugar is minimum and bearable&lt;/li&gt;
&lt;li&gt;Sugar REST API offers everything you need, but can be extended&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Push to Sugar, Sugar pushes to external queue in realtime&lt;span&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;Uses Sugar Events to trigger through Logic Hooks&lt;/li&gt;
&lt;li&gt;Requires&amp;nbsp;Logic Hooks to be created and deployed&lt;/li&gt;
&lt;li&gt;Does not offer &amp;quot;retry mechanism&amp;quot;, if a logic hook fails to deliver to a queue or contact external system&lt;/li&gt;
&lt;li&gt;Synchronous in nature, requires a response from external system&lt;/li&gt;
&lt;li&gt;Needs to handle dependencies manually (contact can only be created after account)&lt;/li&gt;
&lt;li&gt;Good to have a middleware/queue in front of Sugar to receive those event triggers (not mandatory but would make it &amp;quot;asynchronous&amp;quot;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Realtime: Embed your app into Sugar&amp;nbsp;through &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/User_Interface/Dashlets/"&gt;Dashlets&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Simplest approach&lt;/li&gt;
&lt;li&gt;Often requires user-based authentication&lt;/li&gt;
&lt;li&gt;All load/traffic goes directly to your system,&amp;nbsp;careful with&amp;nbsp;bottlenecks&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="register"&gt;&lt;/a&gt;Integrating with Sugar&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Accessing your data when you want is good. &amp;nbsp;Accessing your data however you want is better. &lt;/span&gt;&lt;span&gt;When you decide to build an integration with Sugar, you&amp;rsquo;ll need an easy way to access and interact with the data stored in Sugar. The REST (&lt;/span&gt;&lt;span&gt;representational state transfer)&lt;/span&gt;&lt;span&gt;&amp;nbsp;API (application programming interface) is perfect for this.&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sugar REST API Overview
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;Fully RESTfull (GET, POST, PUT, DELETE)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;OAuth2 token based&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;All fields and modules are available through the API automatically&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Metadata API provides everything you need to know about your Sugar instance.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/271x140/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.17.45-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Topics
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/new-tutorial-intro-to-the-sugar-rest-api"&gt;Intro to the Sugar REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/how-sugar-rest-api-versioning-works"&gt;How Sugar REST API versioning works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/"&gt;RestAPI Developer Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/sugarcrm-cookbook---the-school-of-rest---part-1"&gt;School of REST blog series&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/"&gt;REST APIs Endpoints&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Extending_Endpoints/"&gt;How to add your own custom endpoints to the REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/API_Exceptions/"&gt;API Exceptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Best_Practices/"&gt;Best practices when integrating and migrating Sugar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="api"&gt;&lt;/a&gt;Common&amp;nbsp;APIs&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;It is important to understand our most commonly used APIs and their functions within Sugar. Your integration might need data within Sugar&amp;#39;s module structure that could potentially change over time, so you can use Metadata for it as well as CRUD onto Sugar.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/273x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.20-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Metadata
&lt;ul&gt;
&lt;li&gt;Endpoint with current system&amp;#39;s structure&lt;/li&gt;
&lt;li&gt;Modules, fields, relationships, layouts&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Use carefully, its payload can be MBs in size, cache as much as possible&lt;/li&gt;
&lt;li&gt;GET /metadata (use filters as much as possible)&lt;/li&gt;
&lt;li&gt;It does not retrieve lables for dropdowns, use language api to do so&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/3-tips-for-using-the-sugar-metadata-api"&gt;3 Tips for using the Sugar Metadata API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Language
&lt;ul&gt;
&lt;li&gt;Endpoint to retrieve labels&lt;/li&gt;
&lt;li&gt;Dropdown list values&lt;/li&gt;
&lt;li&gt;Any language specific content&lt;/li&gt;
&lt;li&gt;GET /lang/&amp;lt;language_code&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CRUD (Create, Read, Update, Delete) records
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_GET"&gt;Read&lt;/a&gt;: &lt;code&gt;GET /&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/module_POST"&gt;Create&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_PUT"&gt;Update&lt;/a&gt;: &lt;code&gt;PUT&amp;nbsp;&lt;span&gt;/&amp;lt;module&amp;gt;/:record&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_DELETE"&gt;Delete&lt;/a&gt;: &lt;code&gt;DELETE&amp;nbsp;/&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_POST"&gt;Filter&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;/filter&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;You can use &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_GET"&gt;GET&lt;/a&gt; as well&lt;/li&gt;
&lt;li&gt;POST solves the issue when a query is too long and hits HTTP limits&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_name_GET"&gt;Retrieve records related to another module&lt;/a&gt;:&amp;nbsp;&lt;code&gt;GET /&amp;lt;module&amp;gt;/:record/link/:link_name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_nameremote_id_POST"&gt;Creates a relationship to a pre-existing record:&lt;/a&gt;&lt;code&gt; POST /&amp;lt;module&amp;gt;/:record/link/:link_name/:remote_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="learn"&gt;&lt;/a&gt;Performance and Best Practices&lt;/h1&gt;
&lt;div class="row"&gt;
&lt;div class="col-xs-12 col-md-9"&gt;
&lt;p&gt;SugarBPM&lt;span class="emoticon" data-url="https://sugarclub.sugarai.com/cfs-file/__key/system/emoji/2122.svg" title="Tm"&gt;&amp;#x2122;&lt;/span&gt;&amp;nbsp;enables administrators to streamline common business processes by managing approvals, sales processes, call triaging, and more. SugarBPM&amp;nbsp;is an easy-to-use business process management (BPM) and workflow tool that adds advanced BPM functionality to Sugar.&lt;/p&gt;
&lt;p&gt;The SugarBPM suite features an extensive toolbox of modules that provide the ability to easily create digital forms and map out robust workflows using a drag-and-drop interface.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/272x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.19.03-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Prerequisites&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Basic knowledge of process design is required.&lt;/li&gt;
&lt;li&gt;Basic knowledge of process standards such as BPMN is preferred. BPMN is a flowchart-based notation used to define business processes within an organization.&lt;/li&gt;
&lt;li&gt;You should know which business processes you want to automate in Sugar.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Administration_Guide/SugarBPM/"&gt;SugarBPM&lt;/a&gt; Overview&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/SugarBPM/Business_Process_Automation_via_SugarBPM/"&gt;Introduction to Business Process Automation via SugarBPM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/SugarBPM/Getting_Started_With_SugarBPM_for_Sugar_Serve/"&gt;Getting Started With SugarBPM for Sugar Serve&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/SugarBPM/Using_SugarBPM_to_Notify_a_Team_or_User_on_Record_Creation/"&gt;Using SugarBPM to Notify a Team or User on Record Creation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/SugarBPM/Understanding_Email_Direction_in_Process_Definitions/"&gt;Understanding Email Direction in Process Definitions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/SugarBPM/Understanding_Round_Robin_Activities_vs_Round_Robin_Actions/"&gt;Understanding Round Robin Activities vs. Round Robin Actions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/h1&gt;
&lt;h3 id="mcetoc_1f5uvkqns0"&gt;&lt;span style="font-size:inherit;"&gt;You&amp;#39;re up and running, but don&amp;#39;t stop now - this is just the beginning of your journey. Now it&amp;#39;s time to &lt;a href="/dev-club/dev-onboarding/w/documentation/686/customization-for-devs"&gt;Customizations&lt;/a&gt;.&lt;/span&gt;&lt;/h3&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Integrations for Devs</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs/revision/10</link><pubDate>Thu, 14 Jul 2022 13:03:07 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:df5ca10a-d211-4e03-9873-9d48feb7b645</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs#comments</comments><description>Revision 10 posted to Dev Tutorials by Rafael Fernandes on 7/14/2022 1:03:07 PM&lt;br /&gt;
&lt;p&gt;&lt;span style="background-color:#ff0000;font-size:150%;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="#register"&gt;&lt;img alt=" " src="/resized-image/__size/272x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.17.45-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#setup"&gt;&lt;img alt=" " src="/resized-image/__size/273x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.00-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#api"&gt;&lt;img alt=" " src="/resized-image/__size/273x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.20-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#learn"&gt;&lt;img alt=" " src="/resized-image/__size/272x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.19.03-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="setup"&gt;&lt;/a&gt;Integration Approaches&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;Sugar platform is extremely powerful and easy to integrate with. Determining the right approach for your use case scenario is the key to success.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/263x136/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.00-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Push/Pull from Sugar via REST API&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Recommended approach&lt;/li&gt;
&lt;li&gt;Developers have full control over integration&lt;/li&gt;
&lt;li&gt;Integration can be stopped and systems will continue to work&lt;/li&gt;
&lt;li&gt;Retry mechanism: Resume integrations at any time (bringing only delta changes through &amp;quot;last_udpdate_time&amp;quot; flags)&lt;/li&gt;
&lt;li&gt;Time delay from/to Sugar is minimum and bearable&lt;/li&gt;
&lt;li&gt;Sugar REST API offers everything you need, but can be extended&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Push to Sugar, Sugar pushes to external queue in realtime&lt;span&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;Uses Sugar Events to trigger through Logic Hooks&lt;/li&gt;
&lt;li&gt;Requires&amp;nbsp;Logic Hooks to be created and deployed&lt;/li&gt;
&lt;li&gt;Does not offer &amp;quot;retry mechanism&amp;quot;, if a logic hook fails to deliver to a queue or contact external system&lt;/li&gt;
&lt;li&gt;Synchronous in nature, requires a response from external system&lt;/li&gt;
&lt;li&gt;Needs to handle dependencies manually (contact can only be created after account)&lt;/li&gt;
&lt;li&gt;Good to have a middleware/queue in front of Sugar to receive those event triggers (not mandatory but would make it &amp;quot;asynchronous&amp;quot;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Realtime: Embed your app into Sugar&amp;nbsp;through &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/User_Interface/Dashlets/"&gt;Dashlets&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Simplest approach&lt;/li&gt;
&lt;li&gt;Often requires user-based authentication&lt;/li&gt;
&lt;li&gt;All load/traffic goes directly to your system,&amp;nbsp;careful with&amp;nbsp;bottlenecks&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="register"&gt;&lt;/a&gt;Integrating with Sugar&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Accessing your data when you want is good. &amp;nbsp;Accessing your data however you want is better. &lt;/span&gt;&lt;span&gt;When you decide to build an integration with Sugar, you&amp;rsquo;ll need an easy way to access and interact with the data stored in Sugar. The REST (&lt;/span&gt;&lt;span&gt;representational state transfer)&lt;/span&gt;&lt;span&gt;&amp;nbsp;API (application programming interface) is perfect for this.&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sugar REST API Overview
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;Fully RESTfull (GET, POST, PUT, DELETE)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;OAuth2 token based&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;All fields and modules are available through the API automatically&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Metadata API provides everything you need to know about your Sugar instance.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/271x140/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.17.45-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Topics
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/new-tutorial-intro-to-the-sugar-rest-api"&gt;Intro to the Sugar REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/how-sugar-rest-api-versioning-works"&gt;How Sugar REST API versioning works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/"&gt;RestAPI Developer Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/sugarcrm-cookbook---the-school-of-rest---part-1"&gt;School of REST blog series&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/"&gt;REST APIs Endpoints&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Extending_Endpoints/"&gt;How to add your own custom endpoints to the REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/API_Exceptions/"&gt;API Exceptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Best_Practices/"&gt;Best practices when integrating and migrating Sugar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="api"&gt;&lt;/a&gt;Common&amp;nbsp;APIs&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;It is important to understand our most commonly used APIs and their functions within Sugar. Your integration might need data within Sugar&amp;#39;s module structure that could potentially change over time, so you can use Metadata for it as well as CRUD onto Sugar.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/273x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.20-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Metadata
&lt;ul&gt;
&lt;li&gt;Endpoint with current system&amp;#39;s structure&lt;/li&gt;
&lt;li&gt;Modules, fields, relationships, layouts&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Use carefully, its payload can be MBs in size, cache as much as possible&lt;/li&gt;
&lt;li&gt;GET /metadata (use filters as much as possible)&lt;/li&gt;
&lt;li&gt;It does not retrieve lables for dropdowns, use language api to do so&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/3-tips-for-using-the-sugar-metadata-api"&gt;3 Tips for using the Sugar Metadata API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Language
&lt;ul&gt;
&lt;li&gt;Endpoint to retrieve labels&lt;/li&gt;
&lt;li&gt;Dropdown list values&lt;/li&gt;
&lt;li&gt;Any language specific content&lt;/li&gt;
&lt;li&gt;GET /lang/&amp;lt;language_code&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CRUD (Create, Read, Update, Delete) records
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_GET"&gt;Read&lt;/a&gt;: &lt;code&gt;GET /&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/module_POST"&gt;Create&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_PUT"&gt;Update&lt;/a&gt;: &lt;code&gt;PUT&amp;nbsp;&lt;span&gt;/&amp;lt;module&amp;gt;/:record&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecord_DELETE"&gt;Delete&lt;/a&gt;: &lt;code&gt;DELETE&amp;nbsp;/&amp;lt;module&amp;gt;/:record&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_POST"&gt;Filter&lt;/a&gt;: &lt;code&gt;POST /&amp;lt;module&amp;gt;/filter&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;You can use &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulefilter_GET"&gt;GET&lt;/a&gt; as well&lt;/li&gt;
&lt;li&gt;POST solves the issue when a query is too long and hits HTTP limits&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_name_GET"&gt;Retrieve records related to another module&lt;/a&gt;:&amp;nbsp;&lt;code&gt;GET /&amp;lt;module&amp;gt;/:record/link/:link_name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/Endpoints/modulerecordlinklink_nameremote_id_POST"&gt;Creates a relationship to a pre-existing record:&lt;/a&gt;&lt;code&gt; POST /&amp;lt;module&amp;gt;/:record/link/:link_name/:remote_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="learn"&gt;&lt;/a&gt;SugarBPM - Advanced Workflow&lt;/h1&gt;
&lt;div class="row"&gt;
&lt;div class="col-xs-12 col-md-9"&gt;
&lt;p&gt;SugarBPM&lt;span class="emoticon" data-url="https://sugarclub.sugarai.com/cfs-file/__key/system/emoji/2122.svg" title="Tm"&gt;&amp;#x2122;&lt;/span&gt;&amp;nbsp;enables administrators to streamline common business processes by managing approvals, sales processes, call triaging, and more. SugarBPM&amp;nbsp;is an easy-to-use business process management (BPM) and workflow tool that adds advanced BPM functionality to Sugar.&lt;/p&gt;
&lt;p&gt;The SugarBPM suite features an extensive toolbox of modules that provide the ability to easily create digital forms and map out robust workflows using a drag-and-drop interface.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/272x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.19.03-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Prerequisites&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Basic knowledge of process design is required.&lt;/li&gt;
&lt;li&gt;Basic knowledge of process standards such as BPMN is preferred. BPMN is a flowchart-based notation used to define business processes within an organization.&lt;/li&gt;
&lt;li&gt;You should know which business processes you want to automate in Sugar.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Administration_Guide/SugarBPM/"&gt;SugarBPM&lt;/a&gt; Overview&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/SugarBPM/Business_Process_Automation_via_SugarBPM/"&gt;Introduction to Business Process Automation via SugarBPM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/SugarBPM/Getting_Started_With_SugarBPM_for_Sugar_Serve/"&gt;Getting Started With SugarBPM for Sugar Serve&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/SugarBPM/Using_SugarBPM_to_Notify_a_Team_or_User_on_Record_Creation/"&gt;Using SugarBPM to Notify a Team or User on Record Creation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/SugarBPM/Understanding_Email_Direction_in_Process_Definitions/"&gt;Understanding Email Direction in Process Definitions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/SugarBPM/Understanding_Round_Robin_Activities_vs_Round_Robin_Actions/"&gt;Understanding Round Robin Activities vs. Round Robin Actions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/h1&gt;
&lt;h3 id="mcetoc_1f5uvkqns0"&gt;&lt;span style="font-size:inherit;"&gt;You&amp;#39;re up and running, but don&amp;#39;t stop now - this is just the beginning of your journey. Now it&amp;#39;s time to &lt;a href="/dev-club/dev-onboarding/w/documentation/686/customization-for-devs"&gt;Customizations&lt;/a&gt;.&lt;/span&gt;&lt;/h3&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Integrations for Devs</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs/revision/9</link><pubDate>Wed, 13 Jul 2022 18:27:27 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:df5ca10a-d211-4e03-9873-9d48feb7b645</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/698/integrations-for-devs#comments</comments><description>Revision 9 posted to Dev Tutorials by Rafael Fernandes on 7/13/2022 6:27:27 PM&lt;br /&gt;
&lt;p&gt;&lt;span style="background-color:#ff0000;font-size:150%;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="#register"&gt;&lt;img alt=" " src="/resized-image/__size/272x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.17.45-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#setup"&gt;&lt;img alt=" " src="/resized-image/__size/273x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.00-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#api"&gt;&lt;img alt=" " src="/resized-image/__size/273x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.20-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="#learn"&gt;&lt;img alt=" " src="/resized-image/__size/272x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.19.03-PM.png" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="setup"&gt;&lt;/a&gt;Integration Approaches&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;Sugar platform is extremely powerful and easy to integrate with. Determining the right approach for your use case scenario is the key to success.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/263x136/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.00-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Push/Pull from Sugar via REST API&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Recommended approach&lt;/li&gt;
&lt;li&gt;Developers have full control over integration&lt;/li&gt;
&lt;li&gt;Integration can be stopped and systems will continue to work&lt;/li&gt;
&lt;li&gt;Retry mechanism: Resume integrations at any time (bringing only delta changes through &amp;quot;last_udpdate_time&amp;quot; flags)&lt;/li&gt;
&lt;li&gt;Time delay from/to Sugar is minimum and bearable&lt;/li&gt;
&lt;li&gt;Sugar REST API offers everything you need, but can be extended&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Push to Sugar, Sugar pushes to external queue in realtime&lt;span&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;Uses Sugar Events to trigger through Logic Hooks&lt;/li&gt;
&lt;li&gt;Requires&amp;nbsp;Logic Hooks to be created and deployed&lt;/li&gt;
&lt;li&gt;Does not offer &amp;quot;retry mechanism&amp;quot;, if a logic hook fails to deliver to a queue or contact external system&lt;/li&gt;
&lt;li&gt;Synchronous in nature, requires a response from external system&lt;/li&gt;
&lt;li&gt;Needs to handle dependencies manually (contact can only be created after account)&lt;/li&gt;
&lt;li&gt;Good to have a middleware/queue in front of Sugar to receive those event triggers (not mandatory but would make it &amp;quot;asynchronous&amp;quot;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Realtime: Embed your app into Sugar&amp;nbsp;through &lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/User_Interface/Dashlets/"&gt;Dashlets&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Simplest approach&lt;/li&gt;
&lt;li&gt;Often requires user-based authentication&lt;/li&gt;
&lt;li&gt;All load/traffic goes directly to your system,&amp;nbsp;careful with&amp;nbsp;bottlenecks&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="register"&gt;&lt;/a&gt;Integrating with Sugar&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span&gt;Accessing your data when you want is good. &amp;nbsp;Accessing your data however you want is better. &lt;/span&gt;&lt;span&gt;When you decide to build an integration with Sugar, you&amp;rsquo;ll need an easy way to access and interact with the data stored in Sugar. The REST (&lt;/span&gt;&lt;span&gt;representational state transfer)&lt;/span&gt;&lt;span&gt;&amp;nbsp;API (application programming interface) is perfect for this.&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sugar REST API Overview
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;Fully RESTfull (GET, POST, PUT, DELETE)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;OAuth2 token based&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;All fields and modules are available through the API automatically&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Metadata API provides everything you need to know about your Sugar instance.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/271x140/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.17.45-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Topics
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/new-tutorial-intro-to-the-sugar-rest-api"&gt;Intro to the Sugar REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/how-sugar-rest-api-versioning-works"&gt;How Sugar REST API versioning works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/"&gt;RestAPI Developer Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/dev-club/b/dev-blog/posts/sugarcrm-cookbook---the-school-of-rest---part-1"&gt;School of REST blog series&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Endpoints/"&gt;REST APIs Endpoints&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/Extending_Endpoints/"&gt;How to add your own custom endpoints to the REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/API_Exceptions/"&gt;API Exceptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Best_Practices/"&gt;Best practices when integrating and migrating Sugar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1f4f3gg1d0"&gt;&lt;span&gt;&lt;a id="api"&gt;&lt;/a&gt;Common APIs&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;span style="background-color:#ff0000;"&gt;todo&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;The Studio and Module Builder section includes topics covering creating, modifying, and troubleshooting custom fields, relationships, dropdown lists, and modules via Sugar&amp;#39;s Studio and Module Builder tools:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/273x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.18.20-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Developer_Guide/Integration/Web_Services/REST_API/#Authentication"&gt;Best Practices When Building Custom Modules&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/Studio_and_Module_Builder/Understanding_Module_Builders_Functions/"&gt;Understanding Module Builder&amp;#39;s Functions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/Studio_and_Module_Builder/Creating_a_Custom_Module_With_Module_Builder/"&gt;Creating a Custom Module With Module Builder&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a title="are custom buttons that can be added to records to enable users to perform quick actions directly from records such as sending an email, creating or editing a related record, and opening an external web page" href="https://support.sugarcrm.com/SmartLinks/Administration_Guide/Developer_Tools/Studio/Action_Buttons/"&gt;Add ActionButtons to your records&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/Studio_and_Module_Builder/Creating_a_Dropdown_Field/"&gt;Creating a Dropdown Field&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/Studio_and_Module_Builder/Creating_Dependent_Dropdown_Lists/"&gt;Creating Dependent Dropdown Lists&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/Studio_and_Module_Builder/Creating_a_Relationship/"&gt;Creating Relationship between Modules&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a title="Role-based views provide a way for administrators to set unique layouts for users depending on their role" href="https://support.sugarcrm.com/Knowledge_Base/Studio_and_Module_Builder/Creating_Role-Based_Record_Views/"&gt;Creating Role-Based Record Views&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/Studio_and_Module_Builder/Creating_Role-Based_Dropdown_Lists/"&gt;Creating Role-Based Dropdown Lists&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/Studio_and_Module_Builder/Editing_a_Modules_Layouts/"&gt;Editing a Module&amp;#39;s Layouts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/Studio_and_Module_Builder/Adding_a_Google_Map_to_a_Module/"&gt;Adding a Google Map to a Module&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;a id="learn"&gt;&lt;/a&gt;SugarBPM - Advanced Workflow&lt;/h1&gt;
&lt;div class="row"&gt;
&lt;div class="col-xs-12 col-md-9"&gt;
&lt;p&gt;SugarBPM&lt;span class="emoticon" data-url="https://sugarclub.sugarai.com/cfs-file/__key/system/emoji/2122.svg" title="Tm"&gt;&amp;#x2122;&lt;/span&gt;&amp;nbsp;enables administrators to streamline common business processes by managing approvals, sales processes, call triaging, and more. SugarBPM&amp;nbsp;is an easy-to-use business process management (BPM) and workflow tool that adds advanced BPM functionality to Sugar.&lt;/p&gt;
&lt;p&gt;The SugarBPM suite features an extensive toolbox of modules that provide the ability to easily create digital forms and map out robust workflows using a drag-and-drop interface.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;img class="align-right" style="float:right;" alt=" " src="/resized-image/__size/272x141/__key/communityserver-wikis-components-files/00-00-00-00-61/Screen-Shot-2022_2D00_06_2D00_30-at-2.19.03-PM.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Prerequisites&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Basic knowledge of process design is required.&lt;/li&gt;
&lt;li&gt;Basic knowledge of process standards such as BPMN is preferred. BPMN is a flowchart-based notation used to define business processes within an organization.&lt;/li&gt;
&lt;li&gt;You should know which business processes you want to automate in Sugar.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Administration_Guide/SugarBPM/"&gt;SugarBPM&lt;/a&gt; Overview&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/SugarBPM/Business_Process_Automation_via_SugarBPM/"&gt;Introduction to Business Process Automation via SugarBPM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/SugarBPM/Getting_Started_With_SugarBPM_for_Sugar_Serve/"&gt;Getting Started With SugarBPM for Sugar Serve&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/SugarBPM/Using_SugarBPM_to_Notify_a_Team_or_User_on_Record_Creation/"&gt;Using SugarBPM to Notify a Team or User on Record Creation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/SugarBPM/Understanding_Email_Direction_in_Process_Definitions/"&gt;Understanding Email Direction in Process Definitions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.sugarcrm.com/Knowledge_Base/SugarBPM/Understanding_Round_Robin_Activities_vs_Round_Robin_Actions/"&gt;Understanding Round Robin Activities vs. Round Robin Actions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1 id="mcetoc_1g6ls8l4i0"&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/h1&gt;
&lt;h3 id="mcetoc_1f5uvkqns0"&gt;&lt;span style="font-size:inherit;"&gt;You&amp;#39;re up and running, but don&amp;#39;t stop now - this is just the beginning of your journey. Now it&amp;#39;s time to &lt;a href="/dev-club/dev-onboarding/w/documentation/686/customization-for-devs"&gt;Customizations&lt;/a&gt;.&lt;/span&gt;&lt;/h3&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item></channel></rss>