Developer Documentation

Getting Started

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.

The first step is to get yourself a CloudSponge account and tell us the domain name of your website. Once you've done that, we'll issue you a Domain Key and Domain Password and everything else you need to know is right here in the developer documentation.

The CloudSponge Contact Importer can be installed on your website in two different ways...

  1. You can use our widget to get it working in a few minutes.
  2. You can use our API if you want to have full control over the user interface.

Both options allow you to partially replace our branding with your own company name in addition to several other customization options.


The Contact Importer Widget

Our Contact Importer Widget is appropriate for developers who want to get up and running quickly. You can see it in action on our Test Drive page here:

https://www.cloudsponge.com/test-drive

Once you’ve registered a domain name in your CloudSponge account you’ll be given a domain key that we'll refer to as "YOUR_DOMAIN_KEY" in the rest of this documentation.

Basic Installation

This is all you need to get started with CloudSponge, everything else is optional:

<!-- Any link with a class="cs_import" will start the import process -->
<a class="cs_import">Add from Address Book</a>

<!-- This textarea will be populated with the contacts returned by CloudSponge -->
<textarea id="contact_list" style="width:450px;height:82px"></textarea>

<!-- Include these scripts at the bottom of your page to import address books with CloudSponge -->
<script>
var csPageOptions = {
  domain_key:"YOUR_DOMAIN_KEY",
  textarea_id:"contact_list"
};
</script>
<script src="//api.cloudsponge.com/address_books.js"></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.

The Basic Installation code above 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.

Customization Options

You may specify any of the following variables in your csPageOptions hash.

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.
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.
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.
selectionLimit
integer 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 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", "plaxo", "outlook", "addressbook"] Specifies the sources to display on the contact sources page. Available options: facebook, linkedin, gmail, yahoo, windowslive, aol, plaxo, outlook, addressbook
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.
select_account
boolean false When true, forces display of the account selection screen during the OAuth flow. Currently only supported by Gmail.
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 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 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.

cloudsponge Functions
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) example cloudsponge.launch launches the widget. 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: 'yahoo', 'gmail', 'windowslive', 'aol', 'plaxo', 'addressbook', 'outlook'.

The CloudSponge Widget uses an array of Contact objects to represent a user's address book.

Contact Properties
Property Description
contact.first_name The contact's first name.
contact.last_name The contact's last name.
contact.email An array of Email objects for the contact.
contact.phone An array of Phone objects for the contact.
contact.address undefined or an array of Address objects for the contact. Each address has the properties: address and type.
Contact Functions
Function Usage
contact.fullName() Returns a string with the first and last name for the contact joined with a space.
contact.primaryEmail() Returns a string with the primary email address for the contact.
contact.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().

Email addresses are represented by an object with an address and type.

Email Properties
Property Description
email.address The email address.
email.type The type associated with the email. Possible values depend on the address book source.

Phone numbers are represented by an object with a number and type.

Phone Properties
Property Description
phone.number The phone number.
phone.type The type associated with the phone. Possible values depend on the address book source.

Mailing addresses are represented by an object with address sections and a type.

Mailing Address Properties
Property Description
address.formatted undefined or the full mailing address, formatted with line breaks (\n).
address.street The street portion of the mailing address.
address.city The city portion of the mailing address.
address.region The state or province portion of the mailing address.
address.country The city portion of the mailing address.
address.postal_code The zip or postal code portion of the mailing address.
address.type The type associated with the mailing address. Possible values depend on the address book source.

Sample Code


The Contact Importer 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.

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.

Open Source Library

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. CloudSponge.com cannot guarantee 100% support for these libraries.

Ruby

https://github.com/cloudsponge/cloudsponge-lib-ruby

Java

https://github.com/cloudsponge/cloudsponge-lib-java

PHP

https://github.com/cloudsponge/cloudsponge-lib-php/

.Net

https://github.com/cloudsponge/cloudsponge-lib-net/

ColdFusion *

https://github.com/jojoserquina/cloudsponge-lib-coldfusion/
* Contributed by Jojo Serquina, Senior Developer at SignUpGenius.com


The Do-It-Yourself Approach

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 System Method Endpoint
Facebook-OAuth2.0 import/begin_import/user_consent
LinkedIn-CSV import/begin_import/user_consent
Gmail-OAuth2.0 import/begin_import/user_consent
Outlook.com-OAuth2.0 import/begin_import/user_consent
Yahoo-OAuth import/begin_import/user_consent
AOL-OAuth2.0 import/begin_import/user_consent
Plaxo-Username/Password import/begin_import/import
Outlook1.7u45 <= Java version < 1.7u51CSV import/begin_import/user_consent
OutlookJava version < 1.7u45Applet import/begin_import/desktop_applet
OutlookJava version > 1.7u51Applet import/begin_import/desktop_applet
Mac ContactsJava version >= 1.7u45VCard import/begin_import/user_consent
Mac ContactsChrome w/ Java version > 1.6VCard import/begin_import/user_consent
Mac ContactsJava version < 1.7u45Applet import/begin_import/desktop_applet

  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” URL, including the contact source requested.
    URL: https://api.cloudsponge.com/begin_import/user_consent<format>
    Method: POST
    Parameters:
    • service: Contact source name. One of FACEBOOK, LINKEDIN, GMAIL, YAHOO, WINDOWSLIVE, AOL, OUTLOOK or ADDRESSBOOK.
    • domain_key: Your domain key.
    • domain_password: Your domain password.
    • include (optional): By specifying 'mailing_address' here, mailing addresses will be returned in addition to the other contact information.
    • user_id (optional): Any unique identifier you use to identify a user.
    • echo (optional): Any customer defined string data to be returned in the response.
    • format (optional): either '.json' (default) or '.xml'

    Example:
    https://api.cloudsponge.com/begin_import/user_consent.json \
    ?service=YAHOO \
    &user_id=myUserId_0003 \
    &echo=echo123 \
    &domain_key=33664218758c5244136965160db455db012b1411 \
    &domain_password=Tpa01z+vVPE7MxXi
  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.
    Response:
    • 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 a parameter.
    • echo: The customer defined string that was passed in as a parameter.

    JSON Example:
    {
      "status":"success",
      "url":"https://api.login.yahoo.com/oauth/v2/request_auth?oauth_token=d",
      "import_id":1126,
      "user_id":"myUserId_0003",
      "echo":"echo123"
    }

    XML Example:
    <?xml version="1.0" encoding="UTF-8"?>
    <result>
      <status>success</status>
      <url>https://api.login.yahoo.com/oauth/v2/request_auth?oauth_token=d</url>
      <import-id>1126</import-id>
      <user-id>myUserId_0003</user-id>
      <echo>echo123</echo>
    </result>
  4. Your application redirects the popup to the consent page URL.
  5. Your application's main page goes to Step 2 while the user gives CloudSponge permission to access their address book and we download it for you.

Regular Import - Plaxo

  1. Your application collects the user's username and password combination for the contact source requested.
  2. Your application calls the “Begin Import” URL, including the username/password plus the contact source requested.
    URL: https://api.cloudsponge.com/begin_import/import<format>
    Method: POST
    Parameters:
    • username: Username for the contact source.
    • password: Password for the contact source.
    • service: Contact source name. (PLAXO)
    • domain_key: Your domain key.
    • domain_password: Your domain password.
    • include (optional): By specifying 'mailing_address' here, mailing addresses will be returned in addition to the other contact information.
    • user_id (optional): Any unique identifier you use to identify a user.
    • echo (optional): Any customer defined string data to be returned in the response.
    • format (optional): either '.json' (default) or '.xml'

    Example:
    https://api.cloudsponge.com/begin_import/import.xml \
    ?username=foo \
    &password=bar \
    &service=PLAXO \
    &user_id=myUserId_0003 \
    &echo=echo123 \
    &domain_key=33664218758c5244136965160db455db012b1411 \
    &domain_password=Tpa01z+vVPE7MxXi
  3. CloudSponge returns a result object indicating the request has been received and specifying an identifier to use for fetching events and contacts.
    Response:
    • 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 a parameter.
    • echo: The customer defined string that was passed in as a parameter.

    JSON Example:
    {
      "status":"success",
      "import_id":1131,
      "user_id":"myUserId_0003",
      "echo":"echo123"
    }

    XML Example:
    <?xml version="1.0" encoding="UTF-8"?>
    <result>
      <status>success</status>
      <import-id>1131</import-id>
      <user-id>myUserId_0003</user-id>
      <echo>echo123</echo>
    </result>
  4. (Optional) Your application displays a status update to the user.
  5. Your application goes to Step 2 while CloudSponge downloads the address book for you.

Desktop Applet - Windows Outlook, Mac Contacts

  1. Your application calls the “Begin Import” URL, including the contact source requested.
    URL: https://api.cloudsponge.com/begin_import/desktop_applet<format>
    Method: POST
    Parameters:
    • service: Contact source name. (OUTLOOK or ADDRESSBOOK)
    • domain_key: Your domain key.
    • domain_password: Your domain password.
    • include (optional): By specifying 'mailing_address' here, mailing addresses will be returned in addition to the other contact information.
    • user_id (optional): Any unique identifier you use to identify a user.
    • echo (optional): Any customer defined string data to be returned in the response.
    • format (optional): either '.json' (default) or '.xml'

    Example:
    https://api.cloudsponge.com/begin_import/desktop_applet.json \
    ?service=ADDRESSBOOK \
    &user_id=myUserId_0003 \
    &echo=echo123 \
    &domain_key=33664218758c5244136965160db455db012b1411 \
    &domain_password=Tpa01z+vVPE7MxXi
  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.
    Response:
    • 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 a parameter.
    • echo: The customer defined string that was passed in as a parameter.

    JSON Example:
    {
      "status":"success",
      "url":"https://api.cloudsponge.com/objects/ContactsApplet_signed.jar",
      "import_id":1132,
      "user_id":"myUserId_0003",
      "echo":"echo123"
    }

    XML Example:
    <?xml version="1.0" encoding="UTF-8"?>
    <result>
      <status>success</status>
      <url>https://api.cloudsponge.com/objects/ContactsApplet_signed.jar</url>
      <import-id>1132</import-id>
      <user-id>myUserId_0003</user-id>
      <echo>echo123</echo>
    </result>
  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 following HTML snippet and rendering it onto the page.
    <!--[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="cookieValue" value="document.cookie"/>
      <param name="importId" value="import_id"/>
      <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="cookieValue" value="document.cookie"/>
        <param name="importId" value="import_id"/>
       <param name="MAYSCRIPT" value="true">

        <!-- Chrome falls through to this innermost applet -->
        <applet archive="url" code="ContactsApplet" height="1" width="1" MAYSCRIPT>
          <param name="cookieValue" value="document.cookie" />
          <param name="importId" value="import_id"/>
          <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]-->
  4. Your application goes to Step 2 while the user gives CloudSponge permission to access their address book and we download it for you.

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.
    URL: https://api.cloudsponge.com/events<format>/<import_id>
    Method: GET
    Parameters:
    • import_id: import_id value returned from the call to begin_import in Step 1.
    • domain_key: Your domain key.
    • domain_password: Your domain password.
    • echo (optional): Any customer defined string data to be returned in the response.
    • format (optional): either '.json' (default) or '.xml'

    Example:
    https://api.cloudsponge.com/events.json/1126 \
    ?echo=echo123 \
    &domain_key=33664218758c5244136965160db455db012b1411 \
    &domain_password=Tpa01z+vVPE7MxXi
  2. CloudSponge returns the current Event result object.
    Response:
    • events: An array of events objects for the specified import_id. See the table below for details.
    • import_id: The identifier for this import.
    • user_id: The customer defined string that was passed in as a parameter.
    • echo: The customer defined string that was passed in as a parameter.

    JSON Example:
    {
      "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
    }

    XML Example:
    <?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 COMPLETED n/a
GATHERING ERROR An error code from the table below.
COMPLETE COMPLETED n/a
COMPLETE ERROR An error code from the table below.

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” URL to retrieve the contacts, specifying the import_id from the initial request.
    URL: https://api.cloudsponge.com/contacts<format>/<import_id>
    Method: GET
    Parameters:
    • import_id: import_id value returned from the call to begin_import in Step 1.
    • domain_key: Your domain key.
    • domain_password: Your domain password.
    • echo (optional): Any customer defined string data to be returned in the response.
    • format (optional): either '.json' (default) or '.xml'

    Example:
    https://api.cloudsponge.com/contacts.json/1126 \
    ?echo=echo123 \
    &domain_key=33664218758c5244136965160db455db012b1411 \
    &domain_password=Tpa01z+vVPE7MxXi
  2. CloudSponge returns the Contacts result object in the format requested.
    Response:
    • 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.
    • user_id: The customer defined string that was passed in as a parameter.
    • echo: The customer defined string that was passed in as a parameter.

    JSON Example:
    {
      "echo":null,
      "user_id":"myUserId_0003",
      "import_id":1126,
      "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"
            }
          ]
        }
      ]
    }

    XML Example:
    <?xml version="1.0" encoding="UTF-8"?>
    <contactsResponse>
      <echo nil="true"></echo>
      <user-id>myUserId_0003</user-id>
      <import-id>1126</import-id>
      <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>

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.com.

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 and Yahoo.

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

The import applet can also be rebranded, although the process is slightly more involed becuase 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.

Rebranding Gmail and Yahoo Imports

The Proxy URL

The delegated authentication techniques provided by Gmail and Yahoo 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 token 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 or Windows Live) and proxy that to CloudSponge.

The page you create on your site to proxy requests needs to accept all GET and POST parameters, make an HTTP connection to https://api.cloudsponge.com/auth, passing the parameters with the request and finally return the literal response. In effect, your Proxy URL is makes it appear to https://api.cloudsponge.com/auth as though our page received the original request.

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 the redirect to CloudSponge, it must proxy the request and include any GET and POST parameters with the payload to CloudSponge.

We have several reference implementations of working Proxy URLs:

  1. PHP (depends on the CloudSponge PHP library)
  2. Ruby (depends on the CloudSponge Ruby gem)
  3. ASP .Net
  4. Groovy & Grails
  5. 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.

Facebook

After you follow these steps, your users will see your domain in the Facebook 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 and POST requests (including the query string and form parameters) to: https://api.cloudsponge.com/auth
  2. Sign into Facebook' developer site.
  3. Select an existing application or create a new one.
  4. Obtain your App ID and App Secret from the application Dashboard. Note these values because you will enter them into the CloudSponge Consumer Credential interface.
  5. Make your app public: Enter a Contact Email. Then click Status & Review and click the toggle to make your app publicly available.
  6. Sign in to your CloudSponge account and add a new Facebook Consumer Credential.
  7. Enter the App ID and App Secret for your Facebook application as well as your Proxy URL.
  8. Submit and test a Facebook import.

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. Your Proxy URL should be set up to proxy all GET and POST requests (including the query string and form parameters) to: https://api.cloudsponge.com/auth
  2. Sign into Google and create a new domain via the manage domains page.
  3. Create a project, or open an existing one.
  4. Under "APIs & auth", Select APIs and turn On the Contacts API.
  5. Under "APIs & auth", Select Consent screen and fill in the Product Name and select the correct Email address.
  6. Select Credentials and click on "Create a new client ID..."
  7. Follow Google's promts until you finally get your Client ID, Client secret and Authorized redirect URI. Note these values because you will enter them into the CloudSponge Consumer Credential interface.
  8. Sign in to your CloudSponge account and add a new Gmail Consumer Credential.
  9. Enter the Client ID, Client secret and one Redirect URI from Google.
  10. 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 and POST 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 both Yahoo Mail and Yahoo Contacts.
  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: API Key (Consumer Key), Shared Secret & Application ID
  7. Sign in to your CloudSponge account and add a new Yahoo Consumer Credential.
  8. Enter the API Key, Shared 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 and POST 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.

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.

Branding applet

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 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 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.