Getting Started

Introduction to CloudSponge

Making your users type their friends email addresses into your refer-a-friend form is a friction point that we’re in business to help you with. Our list of supported address books is growing every week, send us an email if you don’t see one that’s important to you.

The first step is to create your company’s CloudSponge account or get an invitation to your company’s account if someone else already created it.

Once you can log into your account, you’ll see your company’s Universal Snippet that will add our widget to any site you use it on. Everything else you need to know is right here in the developer documentation.

If you’d rather build a completely custom interface, you’re welcome to integrate with our REST API instead of using our widget.

Both options allow you to remove the CloudSponge branding in addition to several other customization options.

No Development Environment Handy? No Problem!

Not everyone has a development environment at their fingertips.That’s OK! You can set up a free account on a cloud development environment like Cloud9 IDE to quickly generate a super simple web page and add our widget to enable access to your address book inside a web page.

Let’s get started.

  1. Sign up for a free Cloud9 account and click the Go to your dashboard link.
  2. In your dashboard, Cloud9 has already created a Demo Project for you. Click the Open button for the Demo Project
  3. In the workspaces panel, open the html folder and double click on index.html to open that file.
  4. Copy and paste your CloudSponge snippet from your CloudSponge.com account into the c9.io index.html file. If you haven’t signed up a CloudSponge account, now’s the time. You’ll need to add the script, the “Add from Address Book” link and the #contacts_list textarea. In your refer-a-friend form, the textarea will be replaced by the “To” field.
  5. Click ‘Run’ at the top of the c9.io workspace.
  6. Click Preview > Live Preview File
  7. This opens the “Hello World” page inside the Cloud9 IDE. The CloudSponge widget doesn’t work when nested inside the IDE so you must click the “Pop Out Into New Window” button in the embedded browser to open the page in a new tab in your browser.
  8. Finally, click the Add from Address Book link that you added to the page to access your address book from your new page.

JavaScript Widget

Our JavaScript widget is appropriate for developers who want to get up and running quickly. You can see it in action on our Test Drive page.

If you don’t like the default style or behavior, read on.

The widget is installed on thousands of websites so the chances are pretty good that you’re not the first person to need whatever you have in mind. If you’re not sure how to get it to do what you want, just write us an email and we’ll help you figure it out.

Basic Installation

Once you’ve created a CloudSponge account, you’ll get your own Universal Snippet that you can add to any page to include our widget there. The snippet is a very basic example of using our widget on a page. It does four things that any widget integration must do:

  1. include your widget javascript,
  2. configure the widget,
  3. provide a way for the end user to launch the widget and,
  4. do something with the user’s contacts.

This is the pattern you’ll follow to get started with CloudSponge. You need to sign in to get your own WIDGET_SCRIPT:

Internet Explorer Caveat

Please be aware of IE’s Protected Mode settings. Your test page and api.cloudsponge.com both need to be in zones with the same Protected Mode setting. Usually, api.cloudsponge.com is in the Internet Zone, and your localhost is in the Local internet Zone.

Our recommendation is to enable Protected Mode for both the Internet Zone and the zone that your test page is in. This ensures that your local environment behaves the same as in production.

This is not typically an issue in production since both sites are in the same IE zone and will be treated with the same Protected Mode.

Linking Options

Once you’ve got our JavaScript loading on the page, the next important step is figuring out how your user is going to invoke the widget. There are two approaches:

  1. The default menu link that’s just a simple anchor tag that opens the widget’s main menu.
  2. Deep links that skip the menu and jump straight to a contact source.

In step 3 above, the Basic Installation code puts an “Add from Address Book” hyperlink on your page that will open our widget to a menu of available contact sources. This is the simplest way to get started. If you want to sort or filter the contact source icons that are displayed on the main menu, use the sources parameter in your csPageOptions.

For example, if you want to display Gmail, Yahoo, LinkedIn, iCloud and OS X Contacts (in that order) then:

window.csPageOptions = {
  sources: ["gmail", "yahoo", "linkedin", "icloud", "addressbook"]
}

In step 3 above, the Basic Installation code puts an “Add from Address Book” hyperlink on your page that will open our widget to a menu of available contact sources.

If you’d like to skip the menu (and eliminate one click for your users) you can use Deep Widget Links instead:

The hyperlinks in the code sample above are basic text; since you are adding this code, you can add css styling and images to suit your site.

You may download a zip file of the icon set below for you if you’d like to use what we’re using.

Google Yahoo AOL Mac OS X Contacts LinkedIn Outlook.com Microsoft Outlook iCloud Plaxo Mail.ru UOL BOL Terra Rediff Sapo GMX 126.com 163.com Yeah.net mail.com Mail2World Naver qq.com Poczta o2 QIP.ru Web.de Yandex

Complete Reference

Options

Options may be set via the window.csPageOptions or by calling cloudsponge.init(options) explicitly.

Updating Widget Options

When you specify options as part of the csPageOptions object, the options are copied into the cloudsponge object’s properties when the page loads. If you need to change options after the page has loaded, you must apply them by calling
cloudsponge.init(options) explicitly.

Variable Type Default Usage
cache_contacts boolean true When this value is true, a cached copy of the user’s contacts will be displayed without prompting the user to provide consent again, if the contacts are available. When set to false, the user will always be prompted to import their contacts, even if they have recently imported. If your users commonly access your site from a public location, like a library, you may want to specify false for this value.
csvProviders object {} Lists which providers should use a file upload as the default method for importing. Currently supported by AOL, WINDOWSLIVE, ADDRESSBOOK and OUTLOOK import sources. See an example here.
displaySelectAllNone boolean true When true, enables the All and None links on the Select Your Contacts page which allow the user to select or de-select all their contacts with a single click. When false, these links are hidden.
include array ["name", "email"] Indicates the data to include when automatically populating the contacts in the textarea. When name is included, then both the name and the email address are set in the textarea in the format name <email>. When name is not included, then only the email addresses are set and no additionally formatting is applied. When mailing_address is included in the array, these will be included with the JSON data passed into the callback methods example. See here for the format of the contacts array.
initiallySelectedContacts boolean false Indicates the initial state of the checkboxes associated with each contact.
inlineOauth boolean or string false When false, OAuth sources will launch a popup window for obtaining authorization from the user. When true, OAuth sources will redirect the entire browser window to obtain authorization. When the authorization flow is complete, the browser will be redirected back to the original page and the widget will open and display the result of the import. You can specify "mobile" which will cause the inline behaviour when the widget loads on a mobile browser only.
Note: This option will work as expected when the URL on your site is less than 256 bytes long and is served using a HTTP GET.
force_mobile_render boolean false When this value is true the widget renders itself with the mobile frame and content. Overrides the widget’s own user-agent detection.
mobile_render boolean false When this value is true and the the widget is viewed on a mobile device the widget renders as a mobile browser optimized version. This option should only be set to true when the page that hosts the widget is also optimized for a mobile browser. Doing otherwise may cause improper scaling on the widget making it unusable. Currently only iOS devices are supported with this feature.
onlyGroupedContacts boolean false When this value is true, contacts that do not belong to a group a omitted from the widget view. This option only applies to Gmail currently.
selectionLimit integer undefined When defined limits the number of contacts that can be selected in the list. Specify a value for selectionLimitMessage to set a custom message. Use with displaySelectAllNone:false.
selectionLimitMessage string undefined Specifies the message to display to the user in an alert box when they attempt to select too many contacts. Ignore it to suppress the message. Has not effect unless used with selectionLimit.
sources array ["gmail", "yahoo", "windowslive", "aol", "outlook", "addressbook", "plaxo"] Specifies the sources to display on the contact sources page. Available options: gmail, yahoo, windowslive, csv, linkedin, aol, icloud, outlook, addressbook, plaxo, mail_ru, uol, bol, terra, rediff, mail126, mail163, mail_yeah_net, gmx, qip_ru, sapo, mailcom, yandex_ru
performEmailValidation boolean true When true, the widget only displays and returns valid SMTP email addresses. This will filter Exchange addresses. Uses the regexp: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
ignoreMultipleEmails boolean false When true, the widget only displays the first email address when a contact has multiples.
selectAccount boolean false When true, forces display of the account selection screen during the OAuth flow. Currently only supported by Gmail.
skipContactFilter boolean false By default the widget will sort contacts and display only contacts that have at least one valid email address. Set this option to true to suppress this behaviour.
skipSourceMenu boolean false You can suppress the display of the Choose Your Address Book page which will hide the ‘Back’ links. The widget will close instead of displaying this page, unless you call cloudsponge.launch() with no arguments.
stylesheet string undefined Specifies a URL to a stylesheet to override the default so that you can make our widget match your website. This URL is included instead of the default widget stylesheet. We recommend using the default stylesheet as a template for your copy. This feature must be enabled by a CloudSponge administrator, please email support@cloudsponge.com to request permission.
textarea_id string undefined The ID of the textarea to automatically populate with a list of the contacts. If this value is unset or invalid, then automatic population of contacts is disabled and the contacts should be received by one of the callback functions described below.

JavaScript Callbacks

You may define any of the following functions in your csPageOptions hash.

Function Usage
afterInit() Called immediately after the widget is completely initialized and any links to launch the widget can be safely enabled. If your page is launching the widget programatically via the widget API, then ensure that you watch for this callback before attempting to launch the widget.
beforeLaunch() Called immediately before the widget is launched either by the user clicking a “cs_import” link or programatically by calling cloudsponge.launch(). If the callback function returns false, then the widget will cancel launching. If the widget has not been initialized, the callback will not be called. No parameters are passed to the callback.
afterLaunch() Called after the widget launches and all UI elements have been created on the page, but the widget content is loaded. No parameters are passed to the callback. This callback can be useful for overriding some css styles on the floatbox container. Example
beforeImport(source) Called immediately after the user finishes any authentication/consent and before CloudSponge begins to import the concats. The source of the contacts is passed into the callback.
afterImport(source, success) Called after CloudSponge completes importing the users contacts. The source of the contacts and a boolean value indicating if the import succeeded (true indicates a successful import) are passed into the callback. Example
beforeDisplayContacts(contacts, source, owner) Called before the Choose Your Contacts page renders. The callback may accept array of contacts, the name of the source of the contacts, and the owner contact. Since this callback occurs before the contacts are displayed and the user has the opportunity to filter them, all the contacts of the user’s address book are passed in at this point. These contacts are not guaranteed to have any email addresses. Returning false from this function will immediately cause the widget to close, thus suppressing the display of the Choose Your Contacts page. Example
afterSubmitContacts(contacts, source, owner) Called after the user clicks the Next button on the Choose Your Contacts page and before the widget overlay is dismissed. The callback may accept array of contacts, the name of the source of the contacts, and the owner contact. Only the contacts that the user selected are passed to the function. All these contacts will have at least one email address. Example
beforeClosing() Called just before the widget closes for any reason. No data is passed into the beforeClosing function.
afterClosing() Called just after the widget closes for any reason. No arguments are passed into function.

JavaScript API

When you include our address_book.js script on your page, we’ll instantiate a Javascript object named cloudsponge. This is a global object and only one instance is permitted on a page.

Function Usage
cloudsponge.init(options) This function may be called before the widget is used, as an alternative to declaring the var csPageOptions. If you want to dynamically change the csPageOptions, cloudsponge.init(..) can be called to update the csPageOptions. Valid keys and values for options are referenced in the widget customization options above.
cloudsponge.launch(source) cloudsponge.launch(source) launches the widget (see an Example). This function does nothing if the widget has not yet completed initialization. This is a handy function for launching the widget on a page load, or when more flexibility is required for starting the import. Passing in a source is optional: when omitted, the widget displays the list of contact sources; when a valid source is specified, the action launches directly to the specific import. Valid sources are: gmail, yahoo, windowslive, csv, linkedin, aol, icloud, outlook, addressbook, plaxo, mail_ru, uol, bol, terra, rediff, mail126, mail163, mail_yeah_net, gmx, qip_ru, sapo, mailcom, yandex_ru

Data Structure

The CloudSponge Widget uses an array of Contact objects to represent a user’s address book. This data structure is most commonly used by developers who implement the beforeDisplayContacts() and afterSubmitContacts() callbacks since it’s passed in as an argument there.

Properties Description
contacts[i].first_name The contact’s first name.
contacts[i].last_name The contact’s last name.
contacts[i].email An array of Email objects for the contact.
contacts[i].email[j].address The email address.
contacts[i].email[j].type The type associated with the email. Possible values depend on the address book source.
contacts[i].phone An array of Phone objects for the contact.
contacts[i].phone[j].number The phone number.
contacts[i].phone[j].type The type associated with the phone number. Possible values depend on the address book source.
contacts[i].address undefined or an array of Address objects for the contact. Each address has the properties: address and type.
contacts[i].address[j].formatted undefined or the full mailing address, formatted with line breaks (\n).
contacts[i].address[j].street The street portion of the mailing address.
contacts[i].address[j].city The city portion of the mailing address.
contacts[i].address[j].region The state or province portion of the mailing address.
contacts[i].address[j].country The city portion of the mailing address.
contacts[i].address[j].postal_code The zip or postal code portion of the mailing address.
contacts[i].address[j].type The type associated with the mailing address. Possible values depend on the address book source.
Functions Usage
contacts[i].fullName() Returns a string with the first and last name for the contact joined with a space.
contacts[i].primaryEmail() Returns a string with the primary email address for the contact.
contacts[i].selectedEmail() Returns a string with the email address that was selected in a drop down list. If the Choose Contacts page was not displayed, it returns the value of contact.primaryEmail().

Sample Code


REST API

CloudSponge offers its very own RESTful Address Book API to connect your web application to the contact sources. Use this method if you want to provide a user experience that is not supported by our widget interface.

Despite there being three different user authentication methods, importing contacts with the API follows a similar 3-stage asynchronous process.

Step 1: Get Permission - Your application initiates an address book import by calling the “Begin Import” URL, specifying the user authentication method, the address book source, plus any other additional information required. The API returns a result object containing a unique identifier for subsequent calls to the API, and in some cases data needs to be displayed in the user’s browser.

Step 2: Wait For Import - Your application polls the “Events” URL and receives a result object indicating the current Import Events. These events notify you of the current progress of the import, if any errors have occurred, or when the import is complete. You can optionally display these Import Events to the user’s browser.

Step 3: Download - Once you have received a successful “complete” Import Event, you can retrieve the contacts payload from the API directly or from a database configured for your account.

Step 1: Get The User’s Permission

This step is a little different depending on which source your user wants to import from.

Which import method should I use?

The table below summarizes which import method to use with each source. Desktop imports use a different import method depending on the configuration of the end user’s system.

Source Service Code System Method Endpoint
LinkedIn linkedin Desktop Browsers Only CSV import /begin_import/user_consent
Generic CSV csv Desktop Browsers Only CSV import /begin_import/user_consent
Gmail gmail - OAuth2.0 import /begin_import/user_consent
iCloud icloud - Username/Password import /begin_import/import
Outlook.com windowslive - OAuth2.0 import /begin_import/user_consent
Yahoo yahoo - OAuth import /begin_import/user_consent
AOL aol - OAuth2.0 import /begin_import/user_consent
Plaxo plaxo - Username/Password import /begin_import/import
Mail.ru mail_ru - OAuth2.0 import /begin_import/user_consent
Outlook outlook 1.7u45 <= Java version < 1.7u51 CSV import /begin_import/user_consent
Outlook outlook Java version < 1.7u45 Applet import /begin_import/desktop_applet
Outlook outlook Java version > 1.7u51 Applet import /begin_import/desktop_applet
OS X Contacts addressbook Java version >= 1.7u45 VCard import /begin_import/user_consent
OS X Contacts addressbook Chrome w/ Java version > 1.6 VCard import /begin_import/user_consent
OS X Contacts addressbook Java version < 1.7u45 Applet import /begin_import/desktop_applet
UOL uol - Username/Password import /begin_import/import
BOL bol - Username/Password import /begin_import/import
Terra terra - Username/Password import /begin_import/import
Rediff rediff - Username/Password import /begin_import/import
Mail.com mailcom - Username/Password import /begin_import/import
GMX gmx - Username/Password import /begin_import/import
126.com mail126 - Username/Password import /begin_import/import
163.com mail163 - Username/Password import /begin_import/import
Yeah.net mail_yeah_net - Username/Password import /begin_import/import
Sapo.pt sapo - Username/Password import /begin_import/import
Yandex.ru yandex_ru - Username/Password import /begin_import/import

This import method will send your user to a new window to grant permission to access their contacts. You will call our API to get the URL that you need to load in this window.

  1. Your application launches a new popup window to accommodate for the user consent URL.
  2. Once the popup launches, your application calls the /begin_import/user_consent endpoint, including the contact source requested.
  3. CloudSponge returns a result object, including the import_id to use to fetch the contacts later and a url for the user consent page, which needs to be displayed to the user in the popup window.
  4. Your application redirects the popup to the consent page url.

Now your application’s main page should go to Step 2 while the user gives CloudSponge permission to access their contacts and we download their address book for you.

Definition
POST https://api.cloudsponge.com/begin_import/user_consent[.format]
Request Arguments
Name Required? Description
domain_key Yes Your domain key.
domain_password Yes Your domain password.
service Yes Service code (see table above)
include No By specifying mailing_address here, mailing addresses will be returned in addition to the other contact information.
user_id No Any unique identifier you use to identify a user. This value will be returned on calls to the /events and /contacts endpoints.
echo No Any customer defined string data to be returned in the response.
Example Request
curl --user 33664218758c5244136965160db455db012b1411:Tpa01z+vVPE7MxXi \
     --request POST \
     --data "service=yahoo" \
     --url "https://api.cloudsponge.com/begin_import/user_consent.json"
Response Variables
Name Description
status success or failure
url User Consent URL where the user’s browser should be directed.
import_id The identifier for this import, used in subsequent calls to fetch events and contacts.
user_id The customer defined string that was passed in as an argument.
echo The customer defined string that was passed in as an argument.
Example Response (JSON)
{  
  "status": "success",
  "url": "https://api.cloudsponge.com/n/FULNW3D",
  "import_id": 1126
}
Example Response (XML)
<?xml version="1.0" encoding="UTF-8"?>
<result>
  <status>success</status>
  <url>https://api.cloudsponge.com/n/FULNW3D</url>
  <import-id>1126</import-id>
</result>

Begin Username/Password Import

This import method requires that you collect your user’s username and password for their address book service.

  1. Your application collects the user’s username and password combination for the contact source requested.
  2. Your application calls the /begin_import/import endpoint, including the username/password plus the contact source requested.
  3. CloudSponge returns a result object indicating the request has been received and specifying an import_id for fetching events and contacts later.
  4. (Optional) Your application displays a status update to the user.

Now your application should go to Step 2 while CloudSponge downloads the address book for you.

Definition
POST https://api.cloudsponge.com/begin_import/import[.format]
Request Arguments
Name Required? Description
domain_key Yes Your domain key.
domain_password Yes Your domain password.
service Yes Service code (see table above)
username Yes Your user’s username for the contact source.
password Yes Your user’s password for the contact source.
include No By specifying mailing_address here, mailing addresses will be returned in addition to the other contact information.
user_id No Any unique identifier you use to identify a user.
echo No Any customer defined string data to be returned in the response.
Example Request
curl --user 33664218758c5244136965160db455db012b1411:Tpa01z+vVPE7MxXi \
     --request POST \
     --data "service=icloud" \
     --data "username=foo" \  
     --data "password=bar" \
     --url "https://api.cloudsponge.com/begin_import/import.json"
Response Variables
Name Description
status success or failure
import_id The identifier for this import, used in subsequent calls to fetch events and contacts.
user_id The customer defined string that was passed in as an argument.
echo The customer defined string that was passed in as an argument.
Example Response (JSON)
{  
  "status": "success",  
  "import_id": 1126  
}
Example Response (XML)
<?xml version="1.0" encoding="UTF-8"?>
<result>
  <status>success</status>
  <import-id>1126</import-id>
</result>

Begin Applet Import

This import method requires that your user grants our applet permission to access the contacts that are stored locally on her computer.

  1. Your application calls the /begin_import/desktop_applet endpoint, including the contact source requested.
  2. CloudSponge returns a result object, including a url for the desktop applet, which needs to be downloaded by the user and an import_id to be used to identify the import to the applet and to fetch the events and contacts.
  3. Your application directs the user’s browser to download the applet from the url provided. This is accomplished by inserting the url and import_id into the HTML snippet at the bottom of this section and rendering it onto the page.

Now your application should go to Step 2 while the user gives CloudSponge permission to access their address book and we download it for you.

Definition
POST https://api.cloudsponge.com/begin_import/desktop_applet[.format]
Request Arguments
Name Required? Description
domain_key Yes Your domain key.
domain_password Yes Your domain password.
service Yes Service code (see table above)
include No By specifying mailing_address here, mailing addresses will be returned in addition to the other contact information.
user_id No Any unique identifier you use to identify a user. This value will be returned on calls to the /events and /contacts endpoints.
echo No Any customer defined string data to be returned in the response.
Example Request
curl --user 33664218758c5244136965160db455db012b1411:Tpa01z+vVPE7MxXi \
     --request POST \
     --data "service=outlook" \
     --url "https://api.cloudsponge.com/begin_import/desktop_applet.json"
Response Variables
Name Description
status success or failure
url Java applet URL to be used to process the import.
import_id The identifier for this import, used in subsequent calls to fetch events and contacts.
user_id The customer defined string that was passed in as an argument.
echo The customer defined string that was passed in as an argument.
Example Response (JSON)
{  
  "status": "success",
  "url": "https://api.cloudsponge.com/objects/ContactsApplet_signed.jar",
  "import_id": 1126  
}
Example Response (XML)
<?xml version="1.0" encoding="UTF-8"?>
<result>
  <status>success</status>
  <url>https://api.cloudsponge.com/objects/ContactsApplet_signed.jar</url>
  <import-id>1126</import-id>
</result>

Insert the url and import_id values into the relevant spots in the HTML below and render it on your page to invoke the applet.

Please note Chrome no longer supports the Java browser plugin so when importing from Outlook or Mac OS X contact on Chrome, use the file upload or iCloud import instead.

<!--[if !IE]> Firefox and others will use outer object -->
<object classid="java:ContactsApplet"
  type="application/x-java-applet"
  archive="[ url ]"
  height="1"
  width="1">
  <!-- Konqueror browser needs the following param -->
  <param name="archive" value="[ url ]" />
  <param name="importId" value="[ import_id ]"/>
  <param name="cookieValue" value="document.cookie"/>
  <param name="MAYSCRIPT" value="true">
<!--<![endif]-->

  <!-- MSIE (Microsoft Internet Explorer) will use inner object -->
  <object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
    codebase="http://java.sun.com/update/1.6.0/jinstall-6u30-windows-i586.cab"
    height="0"
    width="0" >
    <param name="code" value="ContactsApplet" />
    <param name="archive" value="[ url ]" />
    <param name="importId" value="[ import_id ]"/>
    <param name="cookieValue" value="document.cookie"/>
   <param name="MAYSCRIPT" value="true">

    <!-- Chrome falls through to this innermost applet -->
    <applet archive="[ url ]" code="ContactsApplet" height="1" width="1" MAYSCRIPT>
      <param name="importId" value="[ import_id ]"/>
      <param name="cookieValue" value="document.cookie" />
      <param name="MAYSCRIPT" value="true">
      <strong>
        This browser does not have a Java Plug-in.<br />
        <a href="http://java.sun.com/products/plugin/downloads/index.html">
          Get the latest Java Plug-in here.
        </a>
      </strong>
    </applet>
  </object>

<!--[if !IE]> close outer object -->
</object>
<!--<![endif]-->

Step 2: Wait For The Import To Finish

After a contact import is initiated, your application must monitor the events as they are generated from CloudSponge. Use the import_id value that was returned from the call to begin_import to identify the import request to CloudSponge when fetching events.

  1. Your application calls the /events URL to get the current Import Events, specifying the import_id returned in the initial request.
  2. CloudSponge returns the current Event result object.

Please Note The value on this endpoint will only update every second at most. Please limit your queries here to once per second.

Definition
GET https://api.cloudsponge.com/events/[import_id][.format]
Request Arguments
Name Required? Description
domain_key Yes Your domain key.
domain_password Yes Your domain password.
import_id Yes import_id value returned from the call to begin_import in Step 1.
echo No Any customer defined string data to be returned in the response.
Example Request
curl --user 33664218758c5244136965160db455db012b1411:Tpa01z+vVPE7MxXi \
     --url "https://api.cloudsponge.com/events/1126.json"
Response Variables
Name Description
events An array of events objects for the specified import_id. See the table below for details.
import_id The identifier for this import, used in subsequent calls to fetch events and contacts.
user_id The customer defined string that was passed in as an argument to the call to /begin_import.
echo The customer defined string that was passed in as an argument.
Example Response (JSON)
{
  "events": [
    {
      "value": 0,
      "status": "COMPLETED",
      "event_type": "INITIALIZING"
    },
    {
      "value": 2,
      "status": "COMPLETED",
      "event_type": "GATHERING"
    },
    {
      "value": 0,
      "status": "COMPLETED",
      "event_type": "COMPLETE"
    }
  ],
  "echo": null,
  "user_id": "myUserId_0003",
  "import_id": 1126  
}  
Example Response (XML)
<?xml version="1.0" encoding="UTF-8"?>
<eventsResponse>
  <events type="array">
    <event>
      <event-type>INITIALIZING</event-type>
      <status>COMPLETED</status>
      <value type="integer">0</value>
    </event>
    <event>
      <event-type>GATHERING</event-type>
      <status>COMPLETED</status>
      <value type="integer">2</value>
    </event>
    <event>
      <event-type>COMPLETE</event-type>
      <status>COMPLETED</status>
      <value type="integer">0</value>
    </event>
  </events>
  <echo nil="true"></echo>
  <user-id>myUserId_0003</user-id>
  <import-id>1126</import-id>
</eventsResponse>

The following table defines the events array elements. Please note that the XML response will have some extra fields included, we do not recommend that you write your code to depend on these fields since we are in the process of deprecating them.

event-type status value
INITIALIZING INPROGRESS n/a
INITIALIZING COMPLETED n/a
INITIALIZING ERROR An error code from the table below.
GATHERING INPROGRESS Number of contacts gathered so far.
GATHERING ERROR An error code from the table below.
GATHERING COMPLETED n/a
COMPLETE ERROR An error code from the table below.
COMPLETE COMPLETED n/a

The following table defines all of the error codes that you can expect to receive along with status=ERROR elements in the events array.

Error Code Error Category Explanation
1 Failed Could not authenticate the domain key/password.
2 Failed Invalid parameters supplied to begin_import.
256 Failed Unexpected error occurred during webmail import.
257 Failed Webmail import failed.
258 Failed Timeout occurred during webmail import.
259 Failed Username and password are required.
260 Failed Service is required.
261 Failed Unrecognized service selected.
262 Failed The same import failed to authenticate recently.
263 Failed Username and password do not match.
264 Failed The address book is temporarily unavailable, please try again later.
265 Failed This account has been canceled.
266 Failed The account has been blocked. Reset the password to reenable it.
267 Failed Terms of Service have changed for your account. Sign in to your account to enable it.
512 Failed Unknown error occurred during a user consent import.
513 Failed User consent import failed because the domain is not permitted to use the service.
514 Abandoned User consent import failed because the user did not provide consent to access their contacts.
516 Abandoned Consent was not granted within the allotted time.
517 Abandoned The user abandoned the import before consent was granted.
518 Failed Unable to communicate successfully with the address book provider.
528 Failed Unable to retrieve contacts. New Yahoo! users must wait 14 days to use this feature.
768 Failed Unexpected error occurred during applet import.
769 Abandoned Applet failed to import because user did not trust the applet.
770 Failed Applet failed to import because it could not find an appropriate address book to import.
771 Failed Applet failed to submit contacts to CloudSponge.
772 Abandoned The Desktop Applet was not trusted within the allotted time.
773 Abandoned The user abandoned the import before the Desktop Applet was trusted.
774 Abandoned You must allow access to Microsoft Outlook to import your contacts.
775 Failed The import was denied access to Contacts by the OS.
1025 Failed A file was uploaded that is not of type text/csv.
1026 Failed A CSV file was uploaded but could not be parsed.

Step 3: Download The Address Book

When the COMPLETE event is received with the COMPLETED status in Step 2, your application should retrieve the contacts immediately. After a few minutes, they will be deleted from CloudSponge.

  1. Your application calls the /contacts endpoint to retrieve the contacts, specifying the import_id from the initial request.
  2. CloudSponge returns the Contacts result object in the format requested.
Definition
GET https://api.cloudsponge.com/contacts/[import_id][.format]
Request Arguments
Name Required? Description
domain_key Yes Your domain key.
domain_password Yes Your domain password.
import_id Yes import_id value returned from the call to /begin_import in Step 1.
start No For pagination: the 0-based index of the start of the contacts returned. Defaults to 0.
count No For pagination: the maximum number of contacts to return in the contacts array. This value is ignored if start is not included. Defaults to 0 (all contacts).
echo No Any customer defined string data to be returned in the response.
Example Request
curl --user 33664218758c5244136965160db455db012b1411:Tpa01z+vVPE7MxXi \
     --url "https://api.cloudsponge.com/contacts/1126.json?start=0&count=10"
Response Variables
Name Description
contacts An array of contact objects for the specified import_id.
contacts_owner Contact information for the owner of the address book.
import_id The identifier for this import, used in subsequent calls to fetch events and contacts.
start For pagination: The 0-based, starting offset of the array of contacts that are returned.
count For pagination: The number of contacts included in the array of contacts.
total The total number of contacts imported from the address book.
user_id The customer defined string that was passed in as an argument to the call to /begin_import.
echo The customer defined string that was passed in as an argument.
Example Response (JSON)
{
  "echo":null,
  "user_id":"myUserId_0003",
  "import_id":1126,
  "start": 0,
  "count": 2,
  "total": 2,
  "contacts_owner":
    {
      "first_name":"Joe",
      "last_name":"Smith",
      "email":[
        {
          "address":"joe@example.com"
        }
      ]
    },
  "contacts": [
    {
      "first_name":"John",
      "last_name":"Doe",
      "phone": [
        {
          "number":"555-1234",
          "type":"Home"
        },
        {
          "number":"555-2468",
          "type":"Work"
        },
      ],
      "email": [
        {
          "address":"johndoe@nowhere.com",
          "type":"Email 1"
        },
        {
          "address":"second@email.com",
          "type":"Email 2"
        }
      ]
    },
    {
      "first_name":"Jane",
      "last_name":"Smith",
      "phone":[
        {
          "number":"555.5678",
          "type":"Home"
        }
      ],
      "email":[
        {
          "address":"janesmith@nowhere.com",
          "type":"Email 1"
        }
      ],
      "addresses": [
        {
          "street":"3450 Sacramento St., #510",
          "city":"San Francisco",
          "region":"CA",
          "country":"US",
          "postal_code":"94118",
          "formatted":"3450 Sacramento St., #510 San Francisco, CA 94118"
        }
      ]
    }
  ]
}
Example Response (XML)
<?xml version="1.0" encoding="UTF-8"?>
<contactsResponse>
  <echo nil="true"></echo>
  <user-id>myUserId_0003</user-id>
  <import-id>1126</import-id>
  <start>0</start>
  <count>2</count>
  <total>2</total>
  <contacts-owner>
    <first-name>Joe</first-name>
    <last-name>Smith</last-name>
    <email type="array">
      <email>
        <address>joe@example.com</address>
      </email>
    </email>
  </contacts-owner>
  <contacts type="array">
    <contact>
      <first-name>John</first-name>
      <last-name>Doe</last-name>
      <phone type="array">
        <phone>
          <number>555-1234</number>
          <type>Home</type>
        </phone>
        <phone>
          <number>555-2468</number>
          <type>Work</type>
        </phone>
      </phone>
      <email type="array">
        <email>
          <address>johndoe@nowhere.com</address>
          <type>Email 1</type>
        </email>
        <email>
          <address>second@email.com</address>
          <type>Email 2</type>
        </email>
      </email>
    </contact>
    <contact>
      <first-name>Jane</first-name>
      <last-name>Smith</last-name>
      <phone type="array">
        <phone>
          <number>555.5678</number>
          <type>Home</type>
        </phone>
      </phone>
      <email type="array">
        <email>
          <address>janesmith@nowhere.com</address>
          <type>Email 1</type>
        </email>
      </email>
      <address type="array">
        <address>
          <street>3450 Sacramento St., #510</street>
          <city>San Francisco</city>
          <region>CA</region>
          <country>US</country>
          <postal-code>94118</postal-code>
          <formatted>3450 Sacramento St., #510 San Francisco, CA 94118</formatted>
        </address>
      </address>
    </contact>
  </contacts>
</contactsResponse>

API Libraries

We highly recommend that you start by choosing one of the wrappers listed below since most of the hard work is already done, but if you have special needs that aren’t addressed in our wrappers, then feel free to take the do-it-yourself approach.

There are a few open source libraries available, which wrap the API request and response sets into specific programming languages. These may make it easier for you to connect your web application to CloudSponge.

NOTE: These open source libraries have been built by the open source community. We cannot guarantee 100% support for these libraries.


Replacing CloudSponge Branding

Since CloudSponge is the service importing contacts, by default the domain displayed in the user consent window(s) is our domain api.cloudsponge.com. We recognize this may not be an ideal user experience, as your users are unfamiliar with CloudSponge.

CloudSponge offers you the ability customize the user experience with your own company name, domain, logo, fonts, styles, languages and third party consumer credentials so that your users don’t feel like they’ve left your website.

There are 3 main steps to white labelling imports for Gmail, Yahoo, Outlook.com and Mail.ru.

  1. Set up a Proxy URL on your domain
  2. Create developer accounts with Google, Yahoo!, Windows Live and Mail.ru
  3. Configure CloudSponge to use your Google/Yahoo/Outlook.com/Mail.ru developer credentials (Consumer Credentials)

The import applet can also be rebranded, although the process is slightly more involved because it requires you to obtain a code-signing certificate. Read more in the section below.

Branding the AOL experience is only possible if you have an existing developer relationship with AOL.

The Proxy URL

The OAuth flows provided by Gmail, Yahoo, Outlook.com and Mail.ru are designed for a site like yours to request access to a person’s address book. In order for CloudSponge to be able to do the heavy lifting of importing and normalizing the contacts for your site, your application must hand the consent code over to CloudSponge.

You can accomplish this with a special page on your site that we refer to as Proxy URL.

The sole purpose of this page is to accept the token parameters from the contact source (Gmail, Yahoo, Outlook.com or Mail.ru) and proxy that to CloudSponge.

We have recently released a Javascript Proxy URL implementation that has no server-side dependencies. It consists of a
static HTML page and Javascript file which implements the required behaviour.

Complete the following steps to install and test your OAuth proxy endpoint:

  1. Download the files here or review the full gist.
  2. Add auth-proxy.html and auth-proxy.js to the same directory on your web server. Your Proxy URL is done!
  3. Verify the Proxy URL by visiting the auth-proxy.html page on your server.
    You should see some text and a link. Make a note of the URL, you will use this URL as Proxy URL when setting up your Developer Accounts and also the custom branding in CloudSponge.

Next you can set up your branding for each OAuth source, using the URL for auth-proxy.html.

This Javascript implementation page is preferred over our older reference implementations because there are no server-side dependencies. Any site that can host a static HTML page can host the Proxy URL.

Server-side Proxy URL (deprecated)

For new integrations, please use our Javascript Proxy URL. The server-side Proxy URL reference implementations are listed below for reference only.

Your Proxy URL should be a transparent pass-through between the client and api.cloudsponge.com: all request data should be forwarded directly upstream to https://api.cloudsponge.com/auth. Likewise, all response headers and data should be returned directly to the client. The page you create on your site to proxy requests needs to accept all GET parameters, make an HTTP connection to https://api.cloudsponge.com/auth, passing the parameters with the request. When the response comes back from api.cloudsponge.com, the exact headers and body should be returned to the client. The typical gotcha is following redirects: api.cloudsponge.com/auth returns a 302 response in many cases. Ensure that your system is configured to not follow redirects for the proper result.

CloudSponge may return a 302 Found and a Location in the response header. This response header should be returned to the user’s browser. Some platforms will automatically follow redirects so you must ensure that this functionality is turned off on your system.

Important Note: The Proxy URL cannot follow any redirect response from CloudSponge. It must proxy the request and include any GET parameters with the payload to CloudSponge.

We have several reference implementations of working Proxy URLs:

  1. HTML/Javascript - Recommended
  2. PHP (depends on the CloudSponge PHP library)
  3. Ruby (depends on the CloudSponge Ruby gem)
  4. ASP .Net
  5. Java Servlet
  6. Groovy & Grails
  7. Python & Django

Consumer Credentials

For your site’s identity to appear on the authentication screens, you will need to register an application at each of the contact sources. Once registered, you will need to add these credentials to your domain’s profile in your CloudSponge account.

Google (Gmail)

After you follow these steps, your users will see your domain in the Google Authentication window instead of ours.

  1. If you haven’t already done so, create a Proxy URL on your application’s domain.
  2. Sign into Google Developer Console.
  3. Create a new project, or click on an existing one.
  4. At API Manager > Overview, search by Contacts API and click on it:
  5. If the Enable API button is available:
    1. Click on it to use this API.
    2. Click on “Go to Credentials” button (or “Credentials” link at the left).
  6. At Step “1 - Find out what kind of credentials you need”, fill the questions with the following answers:
    1. Which API are you using: Contacts API.
    2. Where will you be calling the API from: Web server.
    3. What data will be you accessing: User data.
    4. Click on “What credentials do I need?” button.
  7. At Step “2 - Create an OAuth 2.0 client ID”:
    1. Fill Name with your app name.
    2. Fill Authorized redirect URIs with your Proxy URL.
    3. Click on Create client ID button.
  8. At Step “3 - Set up the OAuth 2.0 consent screen”:
    1. Check if email address is correct.
    2. Fill Product name shown to users with the app name that will be displayed to your users.
    3. Click on Continue button.
  9. At Step “4 - Download credentials”, click on “Done” button.
  10. Click over your app credentials in order to view details.
  11. Take note of your Client ID, Client secret.
  12. Sign in to your CloudSponge account and add a new Gmail Consumer Credential.
  13. Enter the Client ID, Client secret and the Redirect URI values from Google.
  14. Submit and test a Google import.

Yahoo! (Yahoo! Mail)

After you follow these steps, your users will see your domain in the Yahoo Authentication window instead of ours.

  1. If you haven’t already done so, create a Proxy URL on your application’s domain. Your Proxy URL should be set up to proxy all GET requests including the query string to: https://api.cloudsponge.com/auth
  2. Sign into the Yahoo Developer Portal with a Yahoo ID.
  3. Create a new project to use the Contacts API. This account must have read access to Contacts. Also, we recommend that you set “Read/Write Public and Private” access to Profiles if you intend to use the contact_owner property.
  4. Set the Application Domain to your application’s domain.
  5. Verify your domain with Yahoo.
  6. Record the following values from your Yahoo project: Client ID & Client Secret.
  7. Sign in to your CloudSponge account and add a new Yahoo Consumer Credential.
  8. Enter the Consumer Key, Consumer Secret and Application ID that you recorded above and your Proxy URL from step 1 above.
  9. Submit and test a Yahoo import.

Microsoft (Outlook.com, MSN, Hotmail, Windows Live)

After you follow these steps, your users will see your domain in the Microsoft’s Authentication window instead of ours.

  1. If you haven’t already done so, create a Proxy URL on your application’s domain. Your Proxy URL should be set up to proxy all GET requests including the query string to: https://api.cloudsponge.com/auth
  2. Sign into the Live Connect Developer Center with a Windows Live ID.
  3. Create a New Application and retrieve your Client ID and Client Secret.
  4. Move on to the Applications Settings Page and under API Settings, enter your application’s domain for the Redirect Domain.
  5. Sign in to your CloudSponge account and add a new Outlook.com Consumer Credential.
  6. Enter the Client ID and Client Secret that you recorded above, a URL to your Privacy Policy and your Proxy URL from step 1 above.
  7. Submit and test a Windows Live import.

Microsoft Office 365

After you follow these steps, your users will see your domain in the Microsoft’s Authentication window instead of ours.

  1. If you haven’t already done so, create a Proxy URL on your application’s domain. Your Proxy URL should be set up to proxy all GET requests including the query string to: https://api.cloudsponge.com/auth
  2. Sign into the Office 365 site with you Office 365 credentials.
  3. Go to Admin and click on Admin menu > Azure AD > Login or Create an Account in Azure AD.
  4. In the Azure AD, go into the menu option ACTIVE DIRECTORY.
  5. Select your Company Instance, or create a new Instance.
  6. Go into the Company Instance, and select the APPLICATIONS item in the top menu.
  7. To create a New Application, click in the +ADD button in the bottom menu.
  8. Select: Add an application my organization is developing.
  9. Give it a name, and use the type: WEB APPLICATION AND/OR WEB API.
  10. Add a SIGN ON URL (your application URL, this is completely arbitrary).
  11. Add a APP ID URI, must to be something like this: https://[yourcompany].onmicrosoft.com/[application_name].
  12. After create the Application, click CONFIGURE in the top menu.
  13. Retrieve your Client ID and create a Key on Keys menu, you must to select a expiration time (1 or 2 years), don’t forget to save the key before you leave the page, you will not able to get it again.
  14. Set the REPLY URL to your Proxy URL from step 1.
  15. Set the PERMISSIONS TO OTHER APPLICATIONS to: Office 365 Exchange Online, Application Permissions: “Read contacts in all mailboxes”, and Delegated Permissions: “Read user contacts”.
  16. Save the changes.
  17. Sign in to your CloudSponge account and add a new Office 365 Consumer Credential.
  18. Enter the Client ID and Client Secret that you recorded above, and the REPLY URL where you created the CloudSponge Proxy in step 1 above.
  19. Associate the branding with your site: click Settings, click the Custom Branding button beside your site and choose the new branding in the Office 365 dropdown.
  20. Submit and test a Office 365 import.

You can learn more about Microsoft Azure AD here.

Mail.ru (my.mail.ru)

After you follow these steps, your users will see your domain in the Mail.ru’s Authentication window instead of ours.

  1. If you haven’t already done so, create a Proxy URL on your application’s domain. Your Proxy URL should be set up to proxy all GET requests including the query string to: https://api.cloudsponge.com/auth
  2. Sign into the Mail.ru API with your account (or create one).
  3. Register your application and record the following values from your app: App Id (Id), Private Key (Приватный ключ) and Secret Key (Секретный ключ)
  4. At Website Address (Адрес сайта), enter your application’s redirect domain URL.
  5. Sign in to your CloudSponge account and add a new Mail.ru Consumer Credential.
  6. Enter all values that you recorded above, a URL to your Privacy Policy and your Proxy URL from step 1 above.
  7. Submit and test a Mail.ru import.

Rebranding Our Applet

By default, your users will see api.cloudsponge.com and “Cloud Copy, Inc.” in the dialog that asks them to give our applet permission to run on their computers.

Replacing our domain name with yours is simple and free. Replacing the digital signature with your company name is a little more complicated and will cost you a little money for a certificate from a third party.

Partial Rebranding

After you follow these steps, our domain name will be replaced with yours but the digital signature will still say “Cloud Copy, Inc.”

  1. Download the CloudSponge.com Desktop Applet from https://api.cloudsponge.com/objects/ContactsApplet_signed.jar and store in a public folder on your web server.
  2. Modify your response from the /begin_import/desktop_applet endpoint to always return the URL to your signed copy of the Desktop Applet.

Full Rebranding

After you follow these steps, our domain and our digital signature will be removed from the applet.

  1. Download and install the Java JDK on your server from http://java.sun.com/javase/downloads/widget/jdk6.jsp.
  2. Using ‘keytool’ (supplied with the JDK), obtain a Code Signing Certificate from a certificate authority such as Thawte or Verisign. More information about keytool and jarsigner can be found at http://java.sun.com/javase/6/docs/technotes/tools/index.html#security.
    1. Generate a self-signed certificate using keytool
    2. Generate a CSR using keytool
    3. Send the CSR to the CA
    4. Purchase the certificate
    5. Verify and import the certificate into the keystore generated in #1
  3. Download the CloudSponge.com signed applet from https://api.cloudsponge.com/objects/ContactsApplet_signed.jar.
  4. Use jarsigner to sign the ContactsApplet.jar with your Code Signing Certificate.
  5. Modify your response from the /begin_import/desktop_applet endpoint to always return the URL to your signed copy of the Desktop Applet.
  6. Follow @CloudSpongeTech on Twitter. We’ll tweet a notification whenever we issue an update to the applet.

Whenever you update your copy of the applet, you will be required to repeat #3 and #4. The permission request will appear the same as for #2, but the digital signature displayed will correspond to your Code Signing Certificate.