Integration Guide

CONTENTS

 

Introduction

Information given in this guide will enable you to send page view, product view, add to cart, and purchase behavior to Rejoiner.

The API offered by Rejoiner consists of two complementary parts:  Javascript API and REST API. For most situations you would only be using the Javascript API; However, in some cases (for conversion tracking) you might also want to use our REST API.

Preparation

In order to use our services, you need to properly authenticate your application with Site ID and Domain. In the case of using our REST API, you would be also required to authorize your requests using your API Key and API Secret. These are all available in your account's Implementation tab in your Rejoiner account as shown on the example below:

JavaScript Based Tracking

For a full  endpoints specification please see JavaScript API (v4) appendix.

Basic code snippet

Rejoiner API v4 introduced new functionality which tracks browsed pages and browsed products. Page view tracking is enabled by  default and called whenever our library is loaded. That means, you should place our base snippet on  every page loaded by end users to be able to track page views. Tracking product views, however, requires you to call the  trackProductView endpoint explicitly.
Our base snippet also takes care of collecting other information about an end users behavior on your site. It scans all forms in order to find a customer's e-mail address and associates it with the current order / browsing session. If you want to explicitly set customer data, please check section  Storing information about customers.

All calls to our API would start like this:

Basic JS

<script type='text/javascript'>
var _rejoiner = _rejoiner || [];
_rejoiner.push(['setAccount', 'your site id here']);
_rejoiner.push(['setDomain', '.yourdomain.com']);
(function() {
    var s = document.createElement('script'); s.type = 'text/javascript';
    s.async = true;
    s.src = 'https://cdn.rejoiner.com/js/v4/rejoiner.lib.js';
    var x = document.getElementsByTagName('script')[0];
    x.parentNode.insertBefore(s, x);
})();
</script>

At that point you need to provide your account's data for  setAccount (line 3) and setDomain (line 4) - please add your Site ID and Domain into the designated fields. 

Tracking add to cart activity

Please remember, that all prices sent to our API should be given  in cents ($45.99 => 4599).

In order to start a Rejoiner campaign you need information about product abandonment. There are two main endpoints that will allow you to collect cart data:  setCartData and setCartItem

To collect general information about a transaction, you have to call the  setCartData endpoint:

setCartData example:

_rejoiner.push(['setCartData', {
    'cart_value': 79996, // total value *in cents* - integer
    'cart_item_count': 4,
    'return_url': 'https://yourdomain.com/regeneratecart?id=231234' //link to regenerate cart
}]);

Below is the basic product information that you have to send to Rejoiner. You should also call the  setCartItem endpoint for each item in the cart.

setCartItem example:

_rejoiner.push(['setCartItem', {
    'product_id': 'SKU-1002',
    'name': 'Exclusive TV 1002',
    'category': ['exclusive-items', 'tv', 'bestsellers'], // array of categories the product belongs to
    'price': 29999, // the unit price *in cents*
    'item_qty': 3, // quantity of items
    'qty_price': 89997, // total price *in cents* = item_qty X price
    'product_url': 'https://yourdomain.com/tv/exclusive/SKU-1002', // link to product
    'image_url': 'https://yourdomain.com/assets/SKU-1002.jpg', // link to product image
    'description': 'Best TV ever. And exclusive!'
}]);

These two endpoints will give Rejoiner enough information to start campaigns, personalize email templates, and generate product recommendations.

To let us know when a product(s) has been removed by the user, you can use the  removeCartItem endpoint as seen below. 

removeCartItem example:

_rejoiner.push(['removeCartItem', {'product_id': 'SKU-1002'}]);
Note: You must re-fire setCartData with updated parameters after using the removeCartItem endpoint.

Tracking Conversions

After an order has been completed, Rejoiner needs information about the  conversion that happened.

For tracking conversion you should call  sendConversion endpoint on the receipt / thank you page you use on your site to confirm that an user has placed an order or paid for goods. 

While it's possible to call conversion tracking endpoint without any arguments,  we highly encourage you to call sendConversion with cart_data and cart_items parameters filled
Doing that  will give you greater accuracy as to what has been converted, so please fill these parameters whenever it is possible.

The easiest way to  convert an order is to call sendConversion endpoint without any arguments, but again we encourage you to send all cart parameters in the call for greater accuracy (see example below). 

If abandonment and post-conversion campaigns all target the same confirmation page, use:

sendConversion Example

<script type='text/javascript'>
var _rejoiner = _rejoiner || [];
_rejoiner.push(['setAccount', 'your site id here']);
_rejoiner.push(['setDomain', '.yourdomain.com']);
(function() {
    var s = document.createElement('script'); s.type = 'text/javascript';
    s.async = true;
    s.src = 'https://cdn.rejoiner.com/js/v4/rejoiner.lib.js';
    var x = document.getElementsByTagName('script')[0];
    x.parentNode.insertBefore(s, x);
})();

_rejoiner.push(['sendConversion', {
    cart_data: {
        'cart_value': 79996, // total value *in cents* - integer
        'cart_item_count': 2,
        'customer_order_number': 'ACID/12113/07/16', // external ID of this order
        'promo': 'SUMMERSALE16', // promotional code for this order
        'return_url': 'https://yourdomain.com/my/orders/?id=231234' //link to your order
    },
    cart_items: [
        // first item bought
        {
            'product_id': 'SKU-1002',
            'name': 'Exclusive TV 1002',
            'category': ['exclusive-items', 'tv', 'bestsellers'], // array of categories the product belongs to
            'price': 29999, // the unit price *in cents*
            'item_qty': 3, // quantity of items
            'qty_price': 89997, // total price *in cents* = item_qty X price
            'product_url': 'https://yourdomain.com/tv/exclusive/SKU-1002', // link to product
            'image_url': 'https://yourdomain.com/assets/SKU-1002.jpg', // link to product image
            'my_custom_param_1': 'my custom value 1',
            'my_custom_param_2': 101010101
        },
        // second item bought
        { /* ... */ } 
    ]
}]);
</script>

If abandonment campaigns target "Page A" and post-conversion campaigns target "Page B," use the following for each campaign type:

sendConversion Advanced Example

// for abandonment campaigns target page
_rejoiner.push(["sendConversion", {campaign_type: ["abandonment"], cart_data: { /* ... */ }, cart_items: [ /* ... */ ] }]);
 
// for post-conversion campaigns target page
_rejoiner.push(["sendConversion", {campaign_type: ["conversion"], cart_data: { /* ... */ }, cart_items: [ /* ... */ ] }]);

If one abandonment campaign targets "Page A" and another abandonment campaign targets "Page B," you must declare the campaign ID(s) of each campaign.

sendConversion Advanced Example with Campaign ID

_rejoiner.push(["sendConversion", {campaign_ids: ["517e97c518484d2b1a000000"], cart_data: { /* ... */ }, cart_items: [ /* ... */ ] }]);

Explicitly starting & stopping an order

When you use the setCartData or setCartItem API calls, a new order will automatically be created. If for some reason you want to start an order earlier, you can do that by calling the startNewOrder without any params.

startNewOrder Example

_rejoiner.push(["startNewOrder"]);

You can also completely stop current order and its processing by calling the  clearCartData endpoint (no parameters required). Calling the clearCartData endpoint will detach the current user session from the last order, stop order processing, and will also stop campaigns associated with that order. 

clearCartData Example

_rejoiner.push(["clearCartData"]);

Tracking browse behavior

Tracking page views

Rejoiner API v4 introduced tracking of user activity on site. Each time the library is loaded a page view will be tracked – it will send info to Rejoiner about URL of the webpage where it was loaded. No additional action is necessary.

If you wish to disable that functionality on certain pages that you don't want to track, you can disable tracking with this code:

trackPageView Example

_rejoiner.push(['trackPageView', false]);

Manually tracking page views

There are situations when we may want to manually track page views. Most common scenario is a SPA application, where there are no reloads when a user is browsing through the application. 

In order to track these page views, please call following code:

addPageView Example

_rejoiner.push(['addPageView', {'url': 'https://yourdomain.com/tv/exclusive/SKU-1002'}]);

Tracking product views

In order to build better product recommendations for visitors and create browse abandonment campaigns you should push information about the products a visitor was interested in.

Examples are: product page, landing page for a new product, comparison page, etc.

For each product impression, you can call the  trackProductView endpoint, which you can call in a similar fashion to the setCartItem – one call for each product view you want to record.

Example call:

trackProductView Example

// first product presented to visitor
_rejoiner.push(['trackProductView', {
    'product_id': 'SKU-1002',
    'name': 'Exclusive TV 1002',
    'category': ['exclusive-items', 'tv', 'bestsellers'], // array of categories the product belongs to
    'price': 29999, // the unit price *in cents*
    'product_url': 'https://yourdomain.com/tv/exclusive/SKU-1002', // link to product
    'image_url': ' 'https://yourdomain.com/assets/SKU-1002.jpg' // link to product image
}]);
// second product seen by visitor
_rejoiner.push(['trackProductView', {
    'product_id': 'SKU-1223',
    'name': 'Standard TV 1223',
    'category': ['inexpensive', 'tv'], // array of categories the product belongs to
    'price': 19999, // the unit price *in cents*
    'product_url': 'https://yourdomain.com/tv/inexpensive/SKU-1223', // link to product
    'image_url': ' 'https://yourdomain.com/assets/SKU-1223.jpg' // link to product image
}]);

Storing information about customers

There are two endpoints that will help you send us information about a current visitor. 

setCustomerData Example

_rejoiner.push(['setCustomerData', {
    'age': 23,
    'gender': 'm', // one of 'male', 'female', 'm', 'f'
    'language': 'en', // code as described in ISO 639-1 or ISO 639-2/T or ISO 639-2/B
    'name': 'John'
}]);

List of available language codes

If your website doesn't contain any forms from which our library could intercept visitor's e-mail, you can specify that explicitly:

setCustomerEmail Example

_rejoiner.push(['setCustomerEmail', {'email': 'john.doe@domain.com'}]);

REST API Usage

API URL

API is located under  https://app.rejoiner.com. We don't offer a sandbox environment at the moment, so please be careful.

Authentication

Each Rejoiner user is assigned a pair of keys: API KEY and API SECRET. Both keys are available in the  Implementation panel as mentioned in the Preparation section.

Each call to our API must be signed by using Hash-based Message Authentication Code (HMAC-SHA1 to be precise).
# Authorization header structure
Authorization: Rejoiner API_KEY:base64encode(hmac_sha1(API_SECRET, $http_verb + '\n' + $request_path + '\n' + $request_body))
  
# Notes:
- $http_verb should be uppercase, eg. "POST"
- $request_path is relative and should always start with /, eg. "/api/1.0/site/53b144ad346e71aasb2ed0d9/lead/convert"
- $request_body should be UTF-8 encoded JSON, for GET requests please use empty string
  
# Header example
Authorization: Rejoiner 770d3bfee9c540c4a2ba854444c1059a:Cvx3ONcsY7hf3q9gwb4Kf15xg8c=

Authentication header calculation algorithm explained:

In addition to specifying the API KEY, each request must also be signed using the API SECRET key. Signature is calculated with HMAC-SHA1 (raw binary data) and encoded with Base64, as described below.

  1. Given that you're calling convert lead endpoint with:
    1. request path being: /api/1.0/site/53b144ad346e71aasb2ed0d9/lead/convert
    2. you're calling it with HTTP POST method (aka HTTP verb)
    3. request body being UTF-8 encoded JSON string (or empty string in case of GET requests)
  2. Content to sign consists of request_pathhttp_verb and request_body joined with newline character '\n'
  3. Calculate signature using HMAC-SHA1 method on the content with your API_SECRET as a key
  4. Put together authentication header: Authorization: Rejoiner your_API_KEY:base64(calculatedsignature)
    1. The first part of the header is constant (Authorization: Rejoiner)
    2. The second part consist of your public API_KEY glued together with base64-encoded signature (with colon)

Signature calculation for popular languages:

Calculating Signature in Python

import hmac
import base64
from hashlib import sha1
 
def sign(api_secret, http_verb, request_path, request_body):
    content = '\n'.join((http_verb, request_path, request_body))
    hashed = hmac.new(api_secret.encode('utf-8'), content.encode('utf-8'), sha1)
    return base64.b64encode(hashed.digest())

Calculating Signature in PHP

function sign($api_secret, $http_verb, $request_path, $request_body) {
    $content = "{$http_verb}\n{$request_path}\n{$request_body}";
    $hash = hash_hmac('sha1', $content, $api_secret, true);
    return base64_encode($hash);
}

Calculating Signature in C#

using System;
using System.Security.Cryptography;
using System.Text;
 
public class RejoinerAPI {
    public static String Sign(String secret, String verb, String path, String body) {
        String message = verb + "\n" + path + "\n" + body;
        byte[] secretBytes = Encoding.ASCII.GetBytes(secret);
        byte[] messageBytes = Encoding.ASCII.GetBytes(message);
        HMACSHA1 hmac = new HMACSHA1(secretBytes);
        return Convert.ToBase64String(hmac.ComputeHash(messageBytes));
    }
}

Guidelines

  • Remember to set Content-Type header to application/json.
  • All params in POST requests should be sent in JSON. Responses, where applicable, will also be in JSON.
  • Status codes will be used as meaningful responses in all endpoints:
RESPONSE STATUS MEANING
200 Request was successful
400 Required params were not specified and/or the body was malformed
403 Failed authentication and/or incorrect signature
500 Internal error, contact us for details

Convert Lead

Rejoiner's REST API allows you to send conversion information independently of the page being displayed to a user.

For example: If you want to wait for confirmation on payment and send information about conversion after payment is accepted, you can use our endpoint for converting a lead. 

POST  /api/1.0/site/<site_id>/lead/convert

PARAM NAME   REQUIRED TYPE DESCRIPTION
email Yes String Lead's email address
campaign_id

deprecated

No String | array ID or list of Campaign IDs that should be converted
campaign_type

deprecated

No String Type of the campaign that should be converted ("abandonment" or "conversion")
cart_data   No Object Information about the converted cart (same params as in sendConversion JS endpoint)
cart_value No Integer Value of the cart  in cents.
cart_item_count No Integer Total number of items in cart.
ie: The number of all items in the cart, not just the number of distinct products.
customer_order_number No String External ID of this order.
promo No
String Promotional code for this order.
return_url No String General link to order-related page, like review request, order summary page, order invoice page, etc.
cart_items   No Array of Objects Stores data about cart items of the current session (Array of the same objects as in setCartItem endpoint)
product_id Yes String Unique ID of the product.
name No String Name of the item in cart.
description No String Full description of the item in cart.
category Yes Array of Strings Categories the cart item belongs to.
price No Integer The unit price of the cart item  in cents.
item_qty No Integer The quantity of an item in the cart.
qty_price No  
Integer The unit price X quantity of an item  in cents.
product_url No String An absolute product URL for the cart item.
image_url No String An absolute image URL for the cart item.
Any additional arguments (in cart_items) will be stored as custom fields (string values).

Converts all orders (that have not yet been converted) associated with specified lead email.

Additionally, one of the optional parameters may be specified to target one or multiple campaigns (for example, when a post-conversion campaign has a different goal than the abandonment campaign). For post-conversion campaigns, the conversion will only occur if the campaign was in progress.

Example Request

# Assumes the following values:
# SITE_ID=53b53e65346e712ffe5756f2
# API_KEY=60d870b9d5b6497e9f55689c4ab1f54b
# API_SECRET=4158524bba7a4e5cb88a725c334da24c
 
POST /api/1.0/site/53b53e65346e712ffe5756f2/lead/convert
Authorization: Rejoiner 60d870b9d5b6497e9f55689c4ab1f54b:C9vJttriEN7cikdx4Wej3zcI594=
Content-Type: application/json
 
{"email": "foo@bar.com"}
Note: Response body will always be empty, use the response status code to determine whether the request was successful.
Example of Extended Conversion Call - Recommended
# Assumes the following values:
# SITE_ID=53b53e65346e712ffe5756f2
# API_KEY=60d870b9d5b6497e9f55689c4ab1f54b
# API_SECRET=4158524bba7a4e5cb88a725c334da24c
 
POST /api/1.0/site/53b53e65346e712ffe5756f2/lead/convert
Authorization: Rejoiner 60d870b9d5b6497e9f55689c4ab1f54b:NzSvOuDyLnwM8VoDaCo1iVaxUtk=
Content-Type: application/json
 
{
  'email': 'foo2@bar.com',
  'campaign_id': '1',
  'campaign_type': 'abandonment',
  'cart_data': {
    'cart_value': 79996,
    'cart_item_count': 2
  },
  'cart_items': [{
    'name': 'Item Name',
    'product_id': 'ITM1',
    'price': 19999,
    'product_url': 'http://yoursite.com/productpage',
    'category': ['televisions', 'smart_tv'],
    'item_qty': 2,
    'qty_price': 39998,
    'image_url': 'http://yoursite.com/path/to/image.jpg'
  }, {
    'name': 'Item Name2',
    'product_id': 'ITM2',
    'price': 19999,
    'product_url': 'http://yoursite.com/productpage2',
    'category': ['televisions'],
    'item_qty': 2,
    'qty_price': 39998,
    'image_url': 'http://yoursite.com/path/to/image2.jpg'
  }]
}
Note: Full REST API technical documentation can be  viewed here.

Still need help? Contact Us Contact Us