Nylas API Contacts CRUD Now Supports iCloud
Tags: engineering, api, python, developers
Published: 2018-08-01 18:57:46

---
title: Nylas API Contacts CRUD Now Supports iCloud
published: true 
tags: engineering,API,Python,developers
canonical_url: https://www.nylas.com/blog/nylas-api-contacts-crud-now-supports-icloud
---

[![Contacts API](https://www.nylas.com/hubfs/Contacts%20API.png?t=1533144615569) ](https://www.nylas.com/blog/nylas-api-contacts-crud-now-supports-icloud)

<p>Previously, we <u><a href="https://www.nylas.com/blog/lessons-learned-syncing-800-million-contacts-to-our-database" target="_blank">wrote</a></u> about our development process for shipping the very beginnings of our Contacts v2.0 upgrade which allows developers to sync contact profiles from address books (like Gmail contacts) into SaaS applications with full CRUD features. The initial release allowed developers to sync contacts from Gmail, Microsoft Exchange, Outlook.com, and Office 365 accounts.</p>
<!--more-->
<p>We’re continuing to build these features to service more types of accounts, and we recently released bi-directional sync and CRUD for iCloud contacts. Now with support for iCloud contacts, developers can interface with more CRUD-supported, information-dense contacts:</p>
<p><strong style="color: #0d2b29; font-size: 22px; text-align: center; background-color: transparent;">Before</strong></p>
<p>&nbsp;</p>
<div><img src="https://d2mxuefqeaa7sj.cloudfront.net/s_179522ABF38A809781EC8AE8FF03D3C967C450F67739F5BA854697C9629F4D7A_1532631164280_Screen+Shot+2018-07-26+at+11.52.27+AM.png" alt="null" width="400" style="width: 400px;"></div>
<p>&nbsp;<strong style="color: #0d2b29; font-size: 22px; text-align: center; background-color: transparent;">After</strong></p>
<p>&nbsp;</p>
<div><img src="https://d2mxuefqeaa7sj.cloudfront.net/s_179522ABF38A809781EC8AE8FF03D3C967C450F67739F5BA854697C9629F4D7A_1532631041086_Screen+Shot+2018-07-26+at+11.50.17+AM.png" alt="null" width="349" style="width: 349px;"></div>
<p>&nbsp;</p>
<p><span style="background-color: transparent;">While integrating Contacts v2.0 for iCloud, we ran into a few challenges around multipart formatting, type mapping, and the management of codebase complexity with one-off adaptations for both multipart formatting and type mapping:</span></p>
<p><strong style="background-color: transparent; color: #0d2b29; font-size: 22px; text-align: center;">Multipart Formatting</strong></p>
<p>One substantial hurdle we faced during this build out process was translating between the different contact providers and our contact models. Each contact provider has its own system and format for collecting contact data. Google has a straightforward interface for its contacts API called <code>gdata</code>, Exchange Active Sync uses tokenized XML through “devices,” and iCloud follows the IETF standard of vCard.</p>
<p>The <u><a href="https://en.wikipedia.org/wiki/VCard" target="_blank">vCard</a></u> format that iCloud implements looks like:</p>
<div><code class="listtype-code listindent1 list-code1 lang-makefile" spellcheck="false"><span class=" author-d-1gg9uz65z1iz85zgdz68zmqkz84zo2qovwsz86z5z71zz76zqz85zwz65zz73zz71zz66zz65zz89zz81zz81z6wz69zz87zz67zz88znkz66zoqht6">BEGIN:VCARD</span></code></div>
<div><code class="listtype-code listindent1 list-code1 lang-makefile" spellcheck="false"><span class=" author-d-1gg9uz65z1iz85zgdz68zmqkz84zo2qovwsz86z5z71zz76zqz85zwz65zz73zz71zz66zz65zz89zz81zz81z6wz69zz87zz67zz88znkz66zoqht6">VERSION:3.0</span></code></div>
<div><code class="listtype-code listindent1 list-code1 lang-makefile" spellcheck="false"><span class=" author-d-1gg9uz65z1iz85zgdz68zmqkz84zo2qovwsz86z5z71zz76zqz85zwz65zz73zz71zz66zz65zz89zz81zz81z6wz69zz87zz67zz88znkz66zoqht6">UID:123456789</span></code></div>
<div><code class="listtype-code listindent1 list-code1" spellcheck="false"><span class=" author-d-1gg9uz65z1iz85zgdz68zmqkz84zo2qovwsz86z5z71zz76zqz85zwz65zz73zz71zz66zz65zz89zz81zz81z6wz69zz87zz67zz88znkz66zoqht6">N:Appleseed;John;;;</span></code></div>
<div><code class="listtype-code listindent1 list-code1" spellcheck="false"><span class=" author-d-1gg9uz65z1iz85zgdz68zmqkz84zo2qovwsz86z5z71zz76zqz85zwz65zz73zz71zz66zz65zz89zz81zz81z6wz69zz87zz67zz88znkz66zoqht6">FN:John Appleseed</span></code></div>
<div><code class="listtype-code listindent1 list-code1 lang-makefile" spellcheck="false"><span class=" author-d-1gg9uz65z1iz85zgdz68zmqkz84zo2qovwsz86z5z71zz76zqz85zwz65zz73zz71zz66zz65zz89zz81zz81z6wz69zz87zz67zz88znkz66zoqht6">NOTE:Good notes</span></code></div>
<div><code class="listtype-code listindent1 list-code1 lang-makefile" spellcheck="false"><span class=" author-d-1gg9uz65z1iz85zgdz68zmqkz84zo2qovwsz86z5z71zz76zqz85zwz65zz73zz71zz66zz65zz89zz81zz81z6wz69zz87zz67zz88znkz66zoqht6">PHOTO;VALUE=uri;X-ABCROP-RECTANGLE=ABClipRect_1&amp;0&amp;205&amp;1115&amp;1115&amp;hP6x6elkonMVk3k9ibig1g==:https://p41-contacts.icloud.com:000/1234567/wbs/abc123</span></code></div>
<div><code class="listtype-code listindent1 list-code1 lang-makefile" spellcheck="false"><span class=" author-d-1gg9uz65z1iz85zgdz68zmqkz84zo2qovwsz86z5z71zz76zqz85zwz65zz73zz71zz66zz65zz89zz81zz81z6wz69zz87zz67zz88znkz66zoqht6">item1.ADR;TYPE=WORK;TYPE=pref:;;695 Minna St;San Francisco;CA;;United States</span></code></div>
<div><code class="listtype-code listindent1 list-code1 lang-makefile" spellcheck="false"><span class=" author-d-1gg9uz65z1iz85zgdz68zmqkz84zo2qovwsz86z5z71zz76zqz85zwz65zz73zz71zz66zz65zz89zz81zz81z6wz69zz87zz67zz88znkz66zoqht6">item1.X-ABADR:us</span></code></div>
<div><code class="listtype-code listindent1 list-code1" spellcheck="false"><span class=" author-d-1gg9uz65z1iz85zgdz68zmqkz84zo2qovwsz86z5z71zz76zqz85zwz65zz73zz71zz66zz65zz89zz81zz81z6wz69zz87zz67zz88znkz66zoqht6">TEL;TYPE=CELL;TYPE=pref;TYPE=VOICE:(415) 604-9500</span></code></div>
<div><code class="listtype-code listindent1 list-code1" spellcheck="false"><span class=" author-d-1gg9uz65z1iz85zgdz68zmqkz84zo2qovwsz86z5z71zz76zqz85zwz65zz73zz71zz66zz65zz89zz81zz81z6wz69zz87zz67zz88znkz66zoqht6">item2.URL;TYPE=pref:http://nylas.com</span></code></div>
<div><code class="listtype-code listindent1 list-code1" spellcheck="false"><span class=" author-d-1gg9uz65z1iz85zgdz68zmqkz84zo2qovwsz86z5z71zz76zqz85zwz65zz73zz71zz66zz65zz89zz81zz81z6wz69zz87zz67zz88znkz66zoqht6">item2.X-ABLABEL:_$!&lt;HomePage&gt;!$_</span></code></div>
<div><code class="listtype-code listindent1 list-code1" spellcheck="false"><span class=" author-d-1gg9uz65z1iz85zgdz68zmqkz84zo2qovwsz86z5z71zz76zqz85zwz65zz73zz71zz66zz65zz89zz81zz81z6wz69zz87zz67zz88znkz66zoqht6">X-AIM;TYPE=HOME;TYPE=pref:aimaddress</span></code></div>
<div><code class="listtype-code listindent1 list-code1 lang-makefile" spellcheck="false"><span class=" author-d-1gg9uz65z1iz85zgdz68zmqkz84zo2qovwsz86z5z71zz76zqz85zwz65zz73zz71zz66zz65zz89zz81zz81z6wz69zz87zz67zz88znkz66zoqht6">IMPP;X-SERVICE-TYPE=aim;TYPE=HOME;TYPE=pref:aim:aimaddress</span></code></div>
<div><code class="listtype-code listindent1 list-code1 lang-makefile" spellcheck="false"><span class=" author-d-1gg9uz65z1iz85zgdz68zmqkz84zo2qovwsz86z5z71zz76zqz85zwz65zz73zz71zz66zz65zz89zz81zz81z6wz69zz87zz67zz88znkz66zoqht6">EMAIL;TYPE=WORK;TYPE=pref;TYPE=INTERNET:</span><span class="attrlink url author-d-1gg9uz65z1iz85zgdz68zmqkz84zo2qovwsz86z5z71zz76zqz85zwz65zz73zz71zz66zz65zz89zz81zz81z6wz69zz87zz67zz88znkz66zoqht6"><a target="_blank" class="attrlink" data-target-href="mailto:support@nylas.com" href="mailto:support@nylas.com" rel="noreferrer nofollow noopener">info@nylas.co</a></span><span class=" author-d-1gg9uz65z1iz85zgdz68zmqkz84zo2qovwsz86z5z71zz76zqz85zwz65zz73zz71zz66zz65zz89zz81zz81z6wz69zz87zz67zz88znkz66zoqht6">m</span></code></div>
<div><code class="listtype-code listindent1 list-code1 lang-makefile" spellcheck="false"><span class=" author-d-1gg9uz65z1iz85zgdz68zmqkz84zo2qovwsz86z5z71zz76zqz85zwz65zz73zz71zz66zz65zz89zz81zz81z6wz69zz87zz67zz88znkz66zoqht6">REV:2018-01-01T00:00:00Z</span></code></div>
<div><code class="listtype-code listindent1 list-code1 lang-makefile" spellcheck="false"><span class=" author-d-1gg9uz65z1iz85zgdz68zmqkz84zo2qovwsz86z5z71zz76zqz85zwz65zz73zz71zz66zz65zz89zz81zz81z6wz69zz87zz67zz88znkz66zoqht6">END:VCARD</span></code></div>
<p><span style="background-color: transparent;">In addition, the parts within a single vCard are different in formatting in small, nuanced ways. Take <code>ADR</code> for example: It follows the format of “{Post Office Address};{Extended Address};{Street};{Locality};{Region};{Postal Code};{Country},” but when iCloud interfaces with the vCard format, the first two parts, Post Office Address and Extended Address, are overall ignored.&nbsp;</span></p>
<div><code class="listtype-code listindent1 list-code1 lang-makefile" spellcheck="false"><span class=" author-d-1gg9uz65z1iz85zgdz68zmqkz84zo2qovwsz86z5z71zz76zqz85zwz65zz73zz71zz66zz65zz89zz81zz81z6wz69zz87zz67zz88znkz66zoqht6">item1.ADR;TYPE=WORK;TYPE=pref:;;695 Minna St;San Francisco;CA;;United States</span></code></div>
<p>There were many other tiny details regarding multipart formatting that significantly slowed down the development process when interfacing directly with the vCard format. We learned that interface documentation (like the vCard format, for example) can only take you so far because implementations (like iCloud) follow details that other providers don’t and remedying this requires testing as many types of contact information as possible. Through the testing process, we also discovered that any name or address that included a semicolon within each contact was always incorrect.&nbsp;</p>
<p>&nbsp;</p>
<p><strong style="color: #0d2b29; font-size: 22px; background-color: transparent;">Type Mapping</strong></p>
<p>As another added complexity to the translation, we learned that on top of weird formatting nuances, iCloud fields also have type mappings that are somewhat unintuitive.&nbsp;</p>
<p>Remember that IMAP example from before?</p>
<div><code class="listtype-code listindent1 list-code1 lang-makefile" spellcheck="false"><span class=" author-d-1gg9uz65z1iz85zgdz68zmqkz84zo2qovwsz86z5z71zz76zqz85zwz65zz73zz71zz66zz65zz89zz81zz81z6wz69zz87zz67zz88znkz66zoqht6">IMPP;X-SERVICE-TYPE=aim;TYPE=HOME;TYPE=pref:aim:aimaddress</span></code></div>
<p>You’ll notice that the URI value <code>aim:aimaddress</code> also prepends a protocol and colon; in this case, it’s <code>aim.</code>&nbsp; Instead of a one-to-one mapping from IMAP service to protocol, the mapping is sometimes many-to-one: both AIM and ICQ use the OSCAR protocol, and iCloud labels this protocol <code>aim</code>. Similarly, QQ and Gadu-Gadu are both labelled with the <code>x-apple</code> protocol.</p>
<p>Although vCard fields like TEL label types with TYPE, IM addresses are different in that they have more “types.” The most important of all is provider, and it’s labeled with X-SERVICE-TYPE.</p>
<div><code class="listtype-code listindent1 list-code1 lang-makefile" spellcheck="false"><span class=" author-d-1gg9uz65z1iz85zgdz68zmqkz84zo2qovwsz86z5z71zz76zqz85zwz65zz73zz71zz66zz65zz89zz81zz81z6wz69zz87zz67zz88znkz66zoqht6">IMPP;X-SERVICE-TYPE=aim;TYPE=HOME;TYPE=pref:aim:aimaddress</span></code></div>
<p><span style="background-color: transparent;">Another example is phone type mappings: A phone labelled as “Home fax” on an iCloud contact is represented as&nbsp;<span class="inline-code author-d-1gg9uz65z1iz85zgdz68zmqkz84zo2qovwsz86z5z71zz76zqz85zwz65zz73zz71zz66zz65zz89zz81zz81z6wz69zz87zz67zz88znkz66zoqht6"><span><code>TYPE=HOME;TYPE=FAX</code></span></span><span class=" author-d-1gg9uz65z1iz85zgdz68zmqkz84zo2qovwsz86z5z71zz76zqz85zwz65zz73zz71zz66zz65zz89zz81zz81z6wz69zz87zz67zz88znkz66zoqht6"> </span>instead of <code>TYPE=HOME FAX</code>. The same is true for a phone labelled as “Work fax”: It’s labelled as <code>TYPE=WORK;TYPE=FAX</code> instead of <code>TYPE=WORK FAX</code>.</span></p>
<p>Determining these complicated mappings required testing with a single contact that had multiple different types of phone numbers and IM addresses. This made it easier to work around these hurdles.</p>
<p>&nbsp;</p>
<p><strong style="color: #0d2b29; font-size: 22px; background-color: transparent;">Managing Codebase Complexity</strong></p>
<p>The growth of our codebase with one-off adaptions for different fields and types was a second order effect of the disconnect between interface and implementation. It made our code reviews harder because the iCloud contacts sync was intermingled with the translation between the vCard and contact, so there was no clear delegation of tasks.</p>
<p>About 2/3 of iCloud v2.0 upgrade’s development was simply this translation. The first half was the pulling of contacts from iCloud, and this complexity was doubled when translating the other way around with CRUD functionality. We realized that we needed a separate adaptor to service the needs of the two-way translation.</p>
<p>Separating the sync and translation functionalities by creating an adaptor solely for iCloud translation reduced our sync logic code by 60% and made our system even more modular. It also made our code reviews a lot easier, which we love!</p>
<p>But reducing all of this complexity for our customers also means that using the Nylas API removes the nightmare of interfacing with implementation-specific details of large protocols and substitutes it with a simple and pleasant experience.</p>
<p>We’d love for you to try it out: head over to our <u><a href="https://docs.nylas.com/reference#contacts-intro" target="_blank">API docs</a></u> or <u><a href="https://www.npmjs.com/package/nylas" target="_blank">one</a></u><a href="https://www.npmjs.com/package/nylas" target="_blank"> </a><u><a href="https://www.npmjs.com/package/nylas" target="_blank">of</a></u><a href="https://www.npmjs.com/package/nylas" target="_blank"> </a><u><a href="https://www.npmjs.com/package/nylas" target="_blank">our</a></u><a href="https://www.npmjs.com/package/nylas" target="_blank"> </a>SDKs to get started.</p>

 ![](https://track.hubspot.com/__ptq.gif?a=3314308&k=14&r=https%3A%2F%2Fwww.nylas.com%2Fblog%2Fnylas-api-contacts-crud-now-supports-icloud&bu=https%253A%252F%252Fwww.nylas.com%252Fblog&bvt=rss)