NAV
cURL JavaScript iOS Android React Native

Introduction

Welcome to PersonaClick API Reference. This reference will help you to create new, more effective S2S or M2S integration.

Our API is RESTful and you can use any language to work with it.

We provide examples as:

Authentication

To authorize, send all requests with shop_id parameter. You can send it both in POST and GET requests.

This parameter identifies your shop.

Some operations require secret API key. You'll provide it in shop_secret parameter.

Initialize

Setup

# No setup is needed
// Put this code in the <head> section of web page.
(function(r){
    window.personaclick=window.personaclick||function(){(window.personaclick.q=window.personaclick.q||[]).push(arguments)};
    var c="https://cdn.personaclick.com",v="/v3.js",s={link:[{href:c,rel:"dns-prefetch"},{href:c,rel:"preconnect"},{href:c+v,rel:"preload",as:"script"}],script:[{src:c+v,async:""}]};
    Object.keys(s).forEach(function(c){s[c].forEach(function(d){var e=document.createElement(c),a;for(a in d)e.setAttribute(a,d[a]);document.head.appendChild(e)})});
})();
// Cocoapods
target '...' do
  // ...
  // Add this
  pod 'PersonaClick'
  // ...
end
// ... and this (to be able to run it on simulators):
post_install do |installer|
  installer.pods_project.build_configurations.each do |config|
    config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
  end
end




// Swift package manager (XCode >= 11)
// 1. Click File menu
// 2. Swift Packages
// 3. Add Package Dependency...
// 4. Specify the git URL for SDK repo: https://github.com/PersonaClick/ios-sdk.git
// 1. Add to dependencies:
implementation 'com.personaclick:personaclick-sdk:+'
implementation 'com.google.firebase:firebase-bom:29.0.3'
implementation 'com.google.firebase:firebase-messaging:23.0.0'


// 2. Append to your project build.gradle
buildscript {
    dependencies {
        ...
        classpath 'com.google.gms:google-services:4.3.10'
    }
}

// 3. Append to your app module build.gradle after line apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'

// 4. Create your app in the Firebase console
//    and copy file google-services.json to your app root path.
//    Sync gradle now.
// Add required packages:
yarn add @personaclick/react-native-sdk
yarn add @react-native-async-storage/async-storage
yarn add react-native-device-info

// For push notifications also add:
yarn add react-native-push-notification
yarn add @react-native-firebase/app
yarn add @react-native-firebase/messaging

// On application launch initialize the SDK:
import PersonaClick from '@personaclick/react-native-sdk';
...
const sdk = new PersonaClick("YOUR_SHOP_ID", "Stream");

// Initialization is async, so you have a method to test, if SDK is initialized or not:
sdk.isInit(); // returns true/false

// To collect push tokens, you have to make some adjustments to the app:

// ** For iOS:

// Open your /ios/{projectName}/AppDelegate.m file, and add the following: At the top of the file, import the Firebase SDK:
import <Firebase.h>

// Open a terminal window and navigate to the location of the Xcode project for your app

cd ios/
pod install

// ** For Android

// In your android/build.gradle

buildscript {
    dependencies {
        ...
        //Add this \/
        classpath 'com.google.gms:google-services:4.3.4'
    }
}

// In your android/app/build.gradle add
apply plugin: 'com.google.gms.google-services'

Before using API you have to setup SDK.

Start session

curl https://api.personaclick.com/init?did=DEVICE_ID&shop_id=SHOP_ID&v=3&sid=SEANCE_ID&referrer=REF_URL
// Put this line right after setup code
personaclick('init', 'SHOP_ID', 'STREAM', success, failure);
import PersonaClick
var sdk = createPersonalizationSDK(shopId: "SHOP_ID", stream: "ios")
// 1. Add code to your application
public class SampleApplication extends Application {
    public void onCreate() {
        super.onCreate();

        //Initialize
        Personaсlick.initialize(getApplicationContext(), SHOP_ID);

        //Notification callback
        Personaсlick.setOnMessageListener(new MessagingService.OnMessageListener() {
            @Override
            public void onMessage(Map<String, String> data) {

                //----->
                //Show your custom notification
                //----->

            }
        });
    }
}

// 2. For On-Premise integration need use initialize with custom api domain:
Personaсlick.initialize(getApplicationContext(), SHOP_ID, API_DOMAIN);

// 3. Check AndroidManifest.xml and add android:name=".SampleApplication" to application item.
<application
        ...
        android:name=".SampleApplication"

GET https://api.personaclick.com/init

Before using SDK or API you have to initialize SDK. Initialization takes current user identifier and requests API for project settings and this user preferences.

Depending on platform there are different requirements when to run init:

If you don't have device identifier (first launch on new device), you have to request API's init method to generate new one. Store this identifier (it's named did) in local storage of mobile application or in database: you'll need it for the future requests to API.

Query Parameters

Parameter Required Description
shop_id true Your API key
did false Is mandatory if you have it. Request without did will generate new one in our DB. Use it as device ID for future requests.
v true Version. Just use 3 as value.
sid true User's temporary identifier for the current session. Must be regenerated every time user starts new session. Unique string. This parameter is handled automatically in all SDKs.
referrer false Referrer page URL for web integration.
tz false Timezone offset (integer, positive or negative number as difference with GMT).
stream false Data stream code. Alphanumeric string (letters, numbers only). Max length: 16. Default: null (means "web"). Can be "ios", "android" or any other string. Used to distinguish between mobile apps, web and other events sources.

Events tracking

You have to track all user's behavior to get real time statistics and user's segmentation.

The platform provides different kinds of events:

Events can be tracked in default mode (user did something) and assisted mode (user did something with help of some platform's instruments: search, push, email, recommendations, etc).

To track assisted events, you need to user recommendedBy (or recommended_by, depending on SDK) params.

Required params

All events require at least these parameters:

Parameter Type Required Description
shop_id String true Your API key
did String true Device ID
sid String true User's current session
event String true Type of an event
stream String false Data stream code. Alphanumeric string (letters, numbers only). Max length: 16. Default: null (means "web"). Can be "ios", "android" or any other string. Used to distinguish between mobile apps, web and other events sources

SDKs already handle these parameters out of the box.

Source tracking

# No code implementation
// It's done automatically. You don't have to do anything.
// Track launch from drip campaign (chain).
// Message ID and source will be provided in mobile push payload
sdk.trackSource(source: .chain, code: "MESSAGE_ID")
Personaсlick.track(Params.TrackEvent.VIEW, "37");
// See click on push notification

For mobile apps you have to track all app launches, happened by drip campaigns, mailings and push notifications. It will allow to track campaigns efficiency properly.

User viewed a product

#Full request without widget recommendation identifiers
curl 'https://api.personaclick.com/push' \
    -X 'POST' \
    -H 'Content-Type: application/json' \
    --data-raw '{"event":"view", "shop_id":"SHOP_ID", "did":"DEVICE_ID", "sid":"SEANCE_ID", "segment":"A or B", "items":[{"id":"PRODUCT_ID"}]}'

#Full request with widget recommendation identifiers
curl 'https://api.personaclick.com/push' \
    -X 'POST' \
    -H 'Content-Type: application/json' \
    --data-raw '{"event":"view", "shop_id":"SHOP_ID", "did":"DEVICE_ID", "sid":"SEANCE_ID", "segment":"A or B", "items":[{"id":"PRODUCT_ID"}], "recommended_by":"dynamic", "recommended_code":"UNIQUE_RECOMMENDER_CODE"}'

#Short request with minimum required parameters
curl 'https://api.personaclick.com/push' \
    -X 'POST' \
    -H 'Content-Type: application/json' \
    --data-raw '{"event":"view", "shop_id":"SHOP_ID", "did":"DEVICE_ID", "items":[{"id":"PRODUCT_ID"}]}'

// Simple track
personaclick("track", "view", "37");

// Also notify the product is in stock (if it was not in stock)
personaclick("track", "view", {
    id: "37",
    stock: true
});

// Or not in stock anymore (to prevent recommending it on the next requests)
personaclick("track", "view", {
    id: "37",
    stock: false
});

// Track if product was viewed after click on product recommendations
personaclick("track", "view", {
    id: "37",
    recommended_by: "dynamic",
    recommended_code: "jkIWdXSRfwVyK"
});

// Track if product was viewed after click on suggest results
personaclick("track", "view", {
    id: "37",
    recommended_by: "instant_search"
});

// ... or on full results
personaclick("track", "view", {
    id: "37",
    recommended_by: "full_search"
});

// Plain tracking
sdk.track(event: .productView(id: "PRODUCT_ID")) { trackResponse in
    print("Product viewed callback")
    switch trackResponse {
    case let .success(response):
        print("Successful")
    case let .failure(error):
        switch error {
        case .custom(let customError):
            print("Error: ", customError)
        default:
            print("Error: ", error.localizedDescription)
        }
        fatalError("Task failed successfully")
    }
}


// Tracking after product recommendation click
let recData = RecomendedBy(type: .dynamic, code: "beb620922934b6ba2d6a3fb82b8b3271")
sdk.track(event: .productView(id: "PRODUCT_ID"), recommendedBy: recData) { trackResponse in
    // ...
}

// View product (simple)
sdk.track("view", "37");

// View product (extended, try to avoid)
sdk.track("view", {
    id: "37",
    stock: true
});

// View product after click on recommender block
sdk.track("view", {
  id: PRODUCT_ID,
  recommended_by: 'dynamic',
  recommended_code: 'UNIQUE_RECOMMENDER_CODE'
});

// View product after search results (instant search)
sdk.track("view", {
  id: PRODUCT_ID,
  recommended_by: 'full_search',
  recommended_code: QUERY_STRING
});

// View product after search results (full search)
sdk.track("view", {
  id: PRODUCT_ID,
  recommended_by: 'instant_search',
  recommended_code: QUERY_STRING
});

Send this event when user opens product's details page.

JS SDK syntax

Syntax
personaclick("track", "view", {params});

JS SDK Parameters

Parameter Type Requirement Description
id string required The ID of the product being viewed
stock boolean optional Product availability. If defined, it overwrites the value received from the product feed (XML) and HTTP-import of the product catalog.
recommended_by string required in some cases If a product from a recommendation widget was opened in a popup or a website uses a "single page" architecture, this parameter must contain the value "dynamic".
recommended_code string required in some cases If a product from the recommendations widget was opened in the pop-up or the site uses a "single page" architecture, this parameter must contain a unique code of the recommendations widget, available in the account in the "data-recommender-code" attribute for each widget.

User viewed a category

#Full request
curl 'https://api.personaclick.com/push' \
    -X 'POST' \
    -H 'Content-Type: application/json' \
    --data-raw '{"event":"category", "shop_id":"SHOP_ID", "did":"DEVICE_ID", "sid":"SEANCE_ID", "segment":"A or B", "category_id":"CATEGORY_ID"}'

#Short request with minimum required parameters
curl 'https://api.personaclick.com/push' \
    -X 'POST' \
    -H 'Content-Type: application/json' \
    --data-raw '{"event":"category", "shop_id":"SHOP_ID", "did":"DEVICE_ID", "category_id":"CATEGORY_ID"}'
personaclick("track", "category", "100500");
sdk.track(event: .categoryView(id: "CATEGORY_ID")) { trackResponse in
    // ... see product viewed event for details about a callback
}
Personaсlick.track(Params.TrackEvent.CATEGORY, (new Params()).put(Params.Parameter.CATEGORY_ID, "100"));
sdk.track("category", "100500");

Send this event when user opens category page.

JS SDK syntax

Syntax
personaclick("track", "category", category_id);

JS SDK Parameters

Parameter Type Requirement Description
category_id string required The ID of the category being viewed

User searched something

#Full request
curl 'https://api.personaclick.com/push' \
    -X 'POST' \
    -H 'Content-Type: application/json' \
    --data-raw '{"event":"search", "shop_id":"SHOP_ID", "did":"DEVICE_ID", "sid":"SEANCE_ID", "segment":"A or B", "search_query":"SEARCH_QUERY"}'

#Short request with minimum required parameters
curl 'https://api.personaclick.com/push' \
    -X 'POST' \
    -H 'Content-Type: application/json' \
    --data-raw '{"event":"search", "shop_id":"SHOP_ID", "did":"DEVICE_ID", "search_query":"SEARCH_QUERY"}'
// Added in iOS SDK 2.1.0
sdk.track(event: .search(query: "red shoes")) { trackResponse in
    // ...
}
personaclick('track', 'search', search_query);
sdk.track("search", "This is a search example");

JS SDK syntax

Syntax
personaclick("track", "search", search_query);

JS SDK Parameters

Parameter Type Requirement Description
search_query string required The search query text

User added product to cart

#Full request for a single product without widget recommendation identifiers
curl 'https://api.personaclick.com/push' \
    -X 'POST' \
    -H 'Content-Type: application/json' \
    --data-raw '{"event":"cart", "shop_id":"SHOP_ID", "did":"DEVICE_ID", "sid":"SEANCE_ID", "segment":"A or B", "items":[{"id":"PRODUCT_ID"}]}'

#Full request for a single product with widget recommendation identifiers
curl 'https://api.personaclick.com/push' \
    -X 'POST' \
    -H 'Content-Type: application/json' \
    --data-raw '{"event":"cart", "shop_id":"SHOP_ID", "did":"DEVICE_ID", "sid":"SEANCE_ID", "segment":"A or B", "items":[{"id":"PRODUCT_ID"}], "recommended_by":"dynamic", "recommended_code":"UNIQUE_RECOMMENDER_CODE"}'

#Short request for a single product with minimum required parameters
curl 'https://api.personaclick.com/push' \
    -X 'POST' \
    -H 'Content-Type: application/json' \
    --data-raw '{"event":"cart", "shop_id":"SHOP_ID", "did":"DEVICE_ID", "items":[{"id":"PRODUCT_ID"}]}'

#Full request to send the full current cart
# Clear all products on our side
curl 'https://api.personaclick.com/push' \
    -X 'POST' \
    -H 'Content-Type: application/json' \
    --data-raw '{"event":"cart", "shop_id":"SHOP_ID", "did":"DEVICE_ID", "sid":"SEANCE_ID", "segment":"A or B", "items":[{"id":"PRODUCT_ID", "amount":"PRODUCT_QUANTITY"}], "full_cart":true}'
//Short request for a single product
personaclick('track', 'cart', 'id');

//Full request for a single product with widget recommendation identifiers
personaclick('track', 'cart', {
    id: PRODUCT_ID,
    amount: PRODUCT_QUANTITY,
    stock: true,
    recommended_by: 'dynamic',
    recommended_code: 'UNIQUE_RECOMMENDER_CODE'
});

//Full request to send the full current cart
personaclick('track', 'cart', [
    {
        id: FIRST_PRODUCT_ID,
        amount: FIRST_PRODUCT_QUANTITY
    },
    ...
    {
        id: LAST_PRODUCT_ID,
        amount: LAST_PRODUCT_QUANTITY
    }
]);

// Full request to send the empty current cart
// Clear all products on our side
personaclick('track', 'cart', []);
// Track product added to cart
sdk.track(event: .productAddedToCart(id: "PRODUCT_ID", amount: 3)) { trackResponse in
    // ... see product viewed event for details about a callback
}

// Sync full cart with products quantity (automatically adds and removes products)
sdk.track(event: .synchronizeCart(items: [CartItem(productId: "784"), CartItem(productId: "785", quantity: 3)]  )) { _ in
  print("Cart is synced callback")
}
//Add to cart (simple)
Personaсlick.track(Params.TrackEvent.CART, "37");

//Add to cart (extended)
Params cart = new Params();
cart
    .put(new Params.Item("37")
        .set(Params.Item.COLUMN.FASHION_SIZE, "M")
        .set(Params.Item.COLUMN.AMOUNT, 2)
    )
    .put(new Params.RecommendedBy(Params.RecommendedBy.TYPE.RECOMMENDATION, "e9ddb9cdc66285fac40c7a897760582a"));
Personaсlick.track(Params.TrackEvent.CART, cart);

//Tracking full cart
Params full_cart = new Params();
full_cart
    .put(Params.Parameter.FULL_CART, true)
    .put(new Params.Item("37")
        .set(Params.Item.COLUMN.AMOUNT, 2)
        .set(Params.Item.COLUMN.FASHION_SIZE, "M")
    )
    .put(new Params.Item("40")
        .set(Params.Item.COLUMN.AMOUNT, 1)
        .set(Params.Item.COLUMN.FASHION_SIZE, "M")
    );
Personaсlick.track(Params.TrackEvent.CART, full_cart);
// Add to cart (simple)
sdk.track("cart", "id");

// Add to cart (from recommender block)
sdk.track("cart", {
  id: PRODUCT_ID,
  amount: PRODUCT_QUANTITY,
  recommended_by: 'dynamic',
  recommended_code: 'UNIQUE_RECOMMENDER_CODE'
});

//Full request to send the full current cart
sdk.track("cart", [
  {
    id: FIRST_PRODUCT_ID,
    amount: FIRST_PRODUCT_QUANTITY
  },
  ...
  {
    id: LAST_PRODUCT_ID,
    amount: LAST_PRODUCT_QUANTITY
  }
]);

JS SDK syntax (short request for a single product)

Syntax
personaclick("track", "cart", "id");

JS SDK Parameters

Parameter Type Requirement Description
id number/string required The ID of the product added to the cart

JS SDK syntax (full request for a single product)

Syntax
personaclick("track", "cart", {params});

JS SDK Parameters

Parameter Type Requirement Description
id string required The ID of the product added to the cart
amount number optional Product quantity
stock boolean optional Product availability. If defined, it overwrites the value received from the product feed (XML) and HTTP-import of the product catalog.
recommended_by string required in some cases If a product from a recommendation widget was opened in a popup or a website uses a "single page" architecture, this parameter must contain the value "dynamic".
recommended_code string required in some cases If a product from the recommendations widget was opened in the pop-up or the site uses a "single page" architecture, this parameter must contain a unique code of the recommendations widget, available in the account in the "data-recommender-code" attribute for each widget.

JS SDK syntax (request to send the full current cart)

Syntax
personaclick("track", "cart", [{params}, ..., {params}]);

JS SDK Parameters

Parameter Type Requirement Description
id string required The ID of the product added to the cart
amount number optional Product quantity

User removed product from cart

#Full request
curl 'https://api.personaclick.com/push' \
    -X 'POST' \
    -H 'Content-Type: application/json' \
    --data-raw '{"event":"remove_from_cart", "shop_id":"SHOP_ID", "did":"DEVICE_ID", "sid":"SEANCE_ID", "segment":"A or B", "items":[{"id":"PRODUCT_ID"}]}'

#Short request for a single product with minimum required parameters
curl 'https://api.personaclick.com/push' \
    -X 'POST' \
    -H 'Content-Type: application/json' \
    --data-raw '{"event":"remove_from_cart", "shop_id":"SHOP_ID", "did":"DEVICE_ID", "items":[{"id":"PRODUCT_ID"}]}'
//Full request for a single product
personaclick('track', 'remove_from_cart', 'id');
sdk.track(event: .productRemovedFromCart(id: "PRODUCT_ID")) { trackResponse in
    // ... see product viewed event for details about a callback
}
// Not described yet
sdk.track("remove_from_cart", id);

JS SDK syntax (full request for a single product)

Syntax
personaclick("track", "remove_from_cart", "id");

JS SDK Parameters

Parameter Type Requirement Description
id string required The ID of the product removed from the cart

User purchased products

#Full request
curl 'https://api.personaclick.com/push' \
    -X 'POST' \
    -H 'Content-Type: application/json' \
    --data-raw '{"event":"purchase", "shop_id":"SHOP_ID", "did":"DEVICE_ID", "email":"[email protected]", "phone": "4400114527199", "sid":"SEANCE_ID", "segment":"A or B", "items":[{"id":"PRODUCT_ID", "price": PRODUCT_PRICE, "amount": PRODUCT_QUANTITY}], "order_id":"ORDER_NUMBER", "order_price":TOTAL_ORDER_PRICE}'

#Short request with minimum required parameters
curl 'https://api.personaclick.com/push' \
    -X 'POST' \
    -H 'Content-Type: application/json' \
    --data-raw '{"event":"purchase", "shop_id":"SHOP_ID", "did":"DEVICE_ID", "sid":"SEANCE_ID", "items":[{"id":"PRODUCT_ID"}]}'
//Full request
personaclick('track', 'purchase', {
      email: "[email protected]",
      phone: "4400114527199",
    products: [
        {id: 37, price: 318, amount: 3},
        {id: 187, price: 5000, amount: 1}
    ],
    order: 'N318',
    order_price: 29999
});
// Track product added to cart
sdk.track(event: .orderCreated(orderId: "123", totalValue: 33.3, products: [(id: "PRODUCT_ID_1", amount: 3, price: 300), (id: "PRODUCT_ID_2", amount: 1, price: 100)])) { trackResponse in
    // ... see product viewed event for details about a callback
}
Params purchase = new Params();
purchase
    .put(new Params.Item("37").set(Params.Item.COLUMN.AMOUNT, 2).set(Params.Item.COLUMN.PRICE, 100))
    .put(Params.Parameter.ORDER_ID, "100234")
    .put(Params.Parameter.ORDER_PRICE, 100500)
  .put(Params.Parameter.DELIVERY_ADDRESS, "1860 street")
    .put(new Params.RecommendedBy(Params.RecommendedBy.TYPE.RECOMMENDATION, "e9ddb9cdc66285fac40c7a897760582a"));
Personaсlick.track(Params.TrackEvent.PURCHASE, purchase);
sdk.track("purchase", {
  products: [
      {id: "37", price: 318, amount: 3},
      {id: "187", price: 5000, amount: 1}
  ],
  order: 'N318',
  order_price: 29999
});

JS SDK syntax

Syntax
personaclick("track", "purchase", {params});

JS SDK Parameters

Parameter Type Requirement Description
products array required An array of objects with product information in the order. Description of parameters in the table below.
order string optional Order number in the store. If not defined, the internal order numbering system will be used. In this case synchronization of order status is impossible.
email string optional Client email.
phone string optional Client phone.
promocode string optional Promo code used in transaction.
order_price number optional The final cost of the order including all discounts, bonuses, and additional services. If not defined, the cost of the order is calculated from the data in the product database without discounts and additional services.
order_cash number optional How much a customer paid with real money.
order_bonuses number optional How much a customer paid with bonuses.
order_delivery number optional Delivery fee.
order_discount number optional Order discount.
delivery_type string optional Method of delivery.
payment_type string optional Payment type. Can by any string value. Ex: cash, card, wire.
tax_free boolean optional Tax free

Description of parameters in the objects of the "products" array:

Parameter Type Requirement Description
id string required The ID of the product in the order
amount number required Product quantity
price number optional Product cost per unit
line_id string optional Unique identifier of the item position in the order on the store's side

User added product to favorites

# Full request
curl 'https://api.personaclick.com/push' \
    -X 'POST' \
    -H 'Content-Type: application/json' \
    --data-raw '{"event":"wish", "shop_id":"SHOP_ID", "did":"DEVICE_ID", "sid":"SEANCE_ID", "items":[{"id":"PRODUCT_ID"}]}'

#Full request to send the full current wish
curl 'https://api.personaclick.com/push' \
    -X 'POST' \
    -H 'Content-Type: application/json' \
    --data-raw '{"event":"wish", "shop_id":"SHOP_ID", "did":"DEVICE_ID", "sid":"SEANCE_ID", "segment":"A or B", "items":["FIRST_PRODUCT_ID", "LAST_PRODUCT_ID"], "full_wish":true}'

#Full request to send the empty current wish
# Clear all products on our side
curl 'https://api.personaclick.com/push' \
    -X 'POST' \
    -H 'Content-Type: application/json' \
    --data-raw '{"event":"wish", "shop_id":"SHOP_ID", "did":"DEVICE_ID", "sid":"SEANCE_ID", "segment":"A or B", "full_wish":true}'
personaclick('track', 'wish', product_id);

// Full request to send the full current wish
personaclick('track', 'wish', [FIRST_PRODUCT_ID, ..., LAST_PRODUCT_ID]);

// Full request to send the empty current wish
// Clear all products on our side
personaclick('track', 'wish', []);
Personaсlick.track(Params.TrackEvent.WISH, "37");
sdk.track(event: .productAddToFavorities(id: "PRODUCT_ID")) { trackResponse in
    // ... see product viewed event for details about a callback
}
sdk.track("wish", id);

User removed product from favorites

#Full request
curl 'https://api.personaclick.com/push' \
    -X 'POST' \
    -H 'Content-Type: application/json' \
    --data-raw '{"event":"remove_wish", "shop_id":"SHOP_ID", "did":"DEVICE_ID", "sid":"SEANCE_ID", "items":[{"id":"PRODUCT_ID"}]}'
personaclick('track', 'remove_wish', product_id);
sdk.track(event: .productRemovedToFavorities(id: "PRODUCT_ID")) { trackResponse in
    // ... see product viewed event for details about a callback
}
Personaсlick.track(Params.TrackEvent.REMOVE_FROM_WISH, "37");
sdk.track("remove_wish", id);

Track custom event

# Basic tracking
curl 'https://api.personaclick.com/push/custom' \
    -X 'POST' \
    -H 'Content-Type: application/json' \
    --data-raw '{"event":"my_event", "shop_id":"SHOP_ID", "did":"DEVICE_ID", "sid":"SEANCE_ID"}'

# With other identifiers
curl 'https://api.personaclick.com/push/custom' \
    -X 'POST' \
    -H 'Content-Type: application/json' \
    --data-raw '{"event":"my_event", "shop_id":"SHOP_ID", "email":"EMAIL", "phone":"PHONE", "loyalty_id":"LOYALTY_ID", "external_id":"EXTERNAL_ID"}'

# With custom parameters
curl 'https://api.personaclick.com/push/custom' \
    -X 'POST' \
    -H 'Content-Type: application/json' \
    --data-raw '{"event":"my_event", "shop_id":"SHOP_ID", "email":"EMAIL", "phone":"PHONE", "loyalty_id":"LOYALTY_ID", "external_id":"EXTERNAL_ID", "category":"event category", "label":"event label", "value":100}'

# With custom time
curl 'https://api.personaclick.com/push/custom' \
    -X 'POST' \
    -H 'Content-Type: application/json' \
    --data-raw '{"event":"my_event", "shop_id":"SHOP_ID", "did":"DEVICE_ID", "sid":"SEANCE_ID", "time": "1652648400"}'

// Simple tracking
personaclick("track", "my_event");

// Tracking with custom parameters
personaclick("track", "my_event", {
    category: "event category",
    label: "event label",
    value: 100
});
// Simple custom event tracking
sdk.trackEvent(event: "something_happened")

// With parameters
sdk.trackEvent(event: "something_happened", category: "important", label: "banner_click", value: 42)
// Simple tracking of custom event
Personaсlick.track("my_event");

// Tracking with additional parameters
Personaсlick.track("my_event", "event category", "event label", 100);
// Simple tracking
sdk.trackEvent('my_event');

// Tracking with custom parameters
sdk.trackEvent('my_event', {
  category: "event category",
  label: "event label",
  value: 100
});

Query Parameters

Parameter Type Required Description
shop_id String true Your API key
email* String true User's email
phone* String true User's phone number
loyalty_id* String true User's loyalty card id
external_id* String true User's shop internal id

Optional parameters

Custom event can be tracked in simple mode (just event name) and advanced mode (with 3 optional parameters).

Parameter Type Requirement Description
category String optional Event category
label String optional Event label
value Integer optional Event value
time* Timestamp optional Event time

User received on mobile push

curl 'https://api.personaclick.com/track/received' \
    -X 'POST' \
    -H 'Content-Type: application/json' \
    --data-raw '{"shop_id":"SHOP_ID", "code":"CODE", "type":"TYPE"}'
// No implementation
sdk.notificationReceived(code: "i7ykuagkjgfs", type: "mobile_push_transactional")
// Automatically called from SDK when receiving data from firebase
// Code and type are received in push notification structure
const params = {
  code: 'CODE',
  type: 'TYPE'
};

// Track when the notification is received and displayed
sdk.notificationReceived(params);

When user clicks on mobile push notification in mobile app, you have to send event to API with code and type parameters.

This method uses separate endpoint:

Endpoint: POST https://api.personaclick.com/track/received

Required params

All events require at least these parameters:

Parameter Type Required Description
shop_id String true Your API key
code String true Message identifier. Value can be taken from push's JSON payload. For Android it's located in id property. In iOS SDK it's src.id
type String true Message type. Value can be taken from push's JSON payload. For Android it's located in type property. In iOS SDK it's src.type

User clicked on mobile push

curl 'https://api.personaclick.com/track/clicked' \
    -X 'POST' \
    -H 'Content-Type: application/json' \
    --data-raw '{"shop_id":"SHOP_ID", "code":"CODE", "type":"TYPE"}'
// No implementation
sdk.notificationClicked(code: "i7ykuagkjgfs", type: "mobile_push_transactional")
// Add notification identification data to the intent
intent.putExtra(Personaсlick.NOTIFICATION_TYPE, data.get("type"));
intent.putExtra(Personaсlick.NOTIFICATION_ID, data.get("id"));

// Add click tracking in the method of activity creation
@Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //For tracking notification clicked
    if( getIntent().getExtras() != null ) {
     Personaсlick.notificationClicked(getIntent().getExtras());
    }
  }
// Code and type are received in push notification structure
const params = {
  code: 'CODE',
  type: 'TYPE'
};

// Track when user clicked the notification
sdk.notificationClicked(params);

When user clicks on mobile push notification in mobile app, you have to send event to API with code and type parameters.

This method uses separate endpoint:

Endpoint: POST https://api.personaclick.com/track/clicked

Required params

All events require at least these parameters:

Parameter Type Required Description
shop_id String true Your API key
code String true Message identifier. Value can be taken from push's JSON payload. For Android it's located in id property. In iOS SDK it's src.id
type String true Message type. Value can be taken from push's JSON payload. For Android it's located in type property. In iOS SDK it's src.type

User closed on mobile push

curl 'https://api.personaclick.com/track/closed' \
    -X 'POST' \
    -H 'Content-Type: application/json' \
    --data-raw '{"shop_id":"SHOP_ID", "code":"CODE", "type":"TYPE"}'
// No implementation
sdk.notificationClosed(code: "i7ykuagkjgfs", type: "mobile_push_transactional")
// Not supported
// Not supported

When user clicks on mobile push notification in mobile app, you have to send event to API with code and type parameters.

This method uses separate endpoint:

Endpoint: POST https://api.personaclick.com/track/closed

Required params

All events require at least these parameters:

Parameter Type Required Description
shop_id String true Your API key
code String true Message identifier. Value can be taken from push's JSON payload. For Android it's located in id property. In iOS SDK it's src.id
type String true Message type. Value can be taken from push's JSON payload. For Android it's located in type property. In iOS SDK it's src.type

Product recommendations

Service provides access to product recommendations endpoint.

Request product recommendations


// No implementation is needed in HTTP

personaclick("recommend", "1fd1b3495137bc3c9299816026acf36f", {item: 100500, exclude: [3, 14, 159, 26535], category: 146, search_query: "To be or not to be", limit: 15, brands: ["Alas", "poor", "Yorick"], categories: [1, 146, 100500]}, function(response) {
  // the functionality of rendering a block of product recommendations
}, function(error) {
  // when something went wrong
});
// Basic request
sdk.recommend(blockId: "BLOCK_ID") { recommendResult in
  print("Callback")
}

// Request with additional data (for example with product ID)
sdk.recommend(blockId: "block_id", currentProductId: "PRODUCT_ID") { recommendResult in
  print("Callback")
}

// Create Recommendations Widget collection programmatically.
public var recommendationsCollectionView = RecommendationsWidgetView()
// Load Recommendations Widget view and setup height and position settings.
DispatchQueue.main.async {
  self.recommendationsCollectionView.loadWidget(sdk: globalSDK, blockId: "bc1f41f40bb4f92a705ec9d5ec2ada42")
  self.view.addSubview(self.recommendationsCollectionView)

  self.recommendationsCollectionView.heightAnchor.constraint(equalToConstant: 460).isActive = true //height
  self.recommendationsCollectionView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 20).isActive = true
  self.recommendationsCollectionView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true //left
  self.recommendationsCollectionView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true //right
}
// Setup Recommendations Widget configuration.
sdk.configuration().recommendations.setWidgetBlock(widgetFontName: "Museo",
  widgetBackgroundColor: "#ffffff",
  widgetBackgroundColorDarkMode: "#000000",
  widgetCellBackgroundColor: "#ffffff",
  widgetCellBackgroundColorDarkMode: "#000000",
  widgetBorderWidth: 1,
  widgetBorderColor: "#c3c3c3",
  widgetBorderColorDarkMode: "#c3c3c3",
  widgetBorderTransparent: 0.4,
  widgetCornerRadius: 9,
  widgetStarsColor: "#ff9500",
  widgetAddToCartButtonText: "Add to cart",
  widgetRemoveFromCartButtonText: "Remove from cart",
  widgetAddToCartButtonFontSize: 17,
  widgetRemoveFromCartButtonFontSize: 14,
  widgetCartButtonTextColor: "#ffffff",
  widgetCartButtonTextColorDarkMode: "#ffffff",
  widgetCartButtonBackgroundColor: "#000000",
  widgetCartButtonBackgroundColorDarkMode: "#ffffff",
  widgetCartButtonNeedOpenWebUrl: false,
  widgetFavoritesIconColor: "#000000",
  widgetFavoritesIconColorDarkMode: "#ffffff",
  widgetPreloadIndicatorColor: "#ffffff"
)

Params params = new Params();
params.put(Params.Parameter.EXTENDED, true);
params.put(Params.Parameter.ITEM, "37");
params.put(Params.Parameter.CATEGORY, "111"); //filter by category
Personaсlick.recommend("RECOMMENDER_CODE", params, new Api.OnApiCallbackListener() {
    @Override
    public void onSuccess(JSONObject response) {
        Log.i(TAG, "Recommender response: " + response.toString());
    }
});

const recommender_code = 'recommender_code';

const params = {
  item: 100500,
  exclude: [3, 14, 159, 26535],
  search_query: "To be or not to be"
 // other params
};

sdk.recommend(recommender_code, params)
  .then((res) => {
    console.log(res);
  })
  .catch((error) => {
    console.log(error);
  });

HTTP Request

GET https://api.personaclick.com/recommend/{%recommender_code%}

Query Parameters

Parameter Required Description
did true Device ID. You get it from init method in SDK.
shop_id true Your API key
sid true Temporary user session ID
recommender_code true ID of product recommendations block. You get it from blocks management UI.
resize_image false Image size (px) to resize. Supported: 120, 140, 160, 180, 200, 220.
extended false Supports: 1 or empty. If 1, it will return all information about recommended products. If omit, it returns only products IDs.

JS SDK syntax

Syntax
personaclick("recommend", code, params, success, error);
Name Type Requirement Description
code string required Unique code of the recommendation block. See this value in the "data-recommender-code" attribute of the block created in account
params object required Object with request parameters
success function required in some cases A callback function, to which the API response will be passed. Response type: object.
error function optionally A callback function that will be called when an error occurs (any HTTP status code other than 200)

Request parameters

Name Type Requirement Description
item number/string required in some cases Product ID. This parameter is mandatory for the requests of blocks that use the algorithms "Similar" and "Also bought".
exclude array optionally Product IDs array, which should be excluded from the recommended products list.
category number/string required in some cases Category ID. This parameter is mandatory for all blocks set on category pages.
search_query string required in some cases The text of the search query. This parameter is mandatory for the requests of blocks that use the "Search" algorithm.
limit number optionally A maximum number of products in the API response.
locations array optionally Array with location IDs. If used, the API response will return products available in the listed locations. Locations must be specified in the XML product feed.
brands array optionally Array with brand names. If used, only the products of the listed brands will be returned in the API response. Brands must be specified in the XML product feed.
exclude_brands array optionally Array with brand names. If used, the API response will exclude the products of the listed brands. Brands must be specified in the XML product feed.
categories array optionally Array with category IDs. If used, the API response will only return products that are included in the listed categories.
discount boolean optionally If used with "true" value, then only those products, the value of which is less than the "oldprice" value, will be returned in the API response. The old price must be specified in the XML product feed.
extended number optionally Supports: 1 or empty. If 1, it will return all information about recommended products. If omit, it returns only products IDs.
prevent_shuffle boolean optionally If true, it disables shuffling of products in the response.
page number optionally The parameter for creating pagination, by default 1. Returns the number of products based on the limit per page.

API response

Name Type Description
html string HTML-code of the block with products. The template is customized in the PersonaClick personal account.
title string The block title. Corresponds to the value of the "Action" element in the block rules.
products array Array with product IDs.
id number Unique block identifier. Corresponds to the block ID in the list of blocks in the PersonaClick personal account.

Search

Service provides 2 types of search: instant (typeahead) and full search.

personaclick("suggest", {search_query: "To be or not to be"}, function(response) {
  // the functionality of rendering a block of instant search
}, function(error) {
  // when something went wrong
});
// Instant search
sdk.suggest(query: "ipho") { searchResult in
  print("Suggest callback")
}
//Instant search
SearchParams params = new SearchParams();
params.put(SearchParams.Parameter.LOCATIONS, "location");
Personaсlick.search("SEARCH_QUERY", SearchParams.TYPE.INSTANT, params, new Api.OnApiCallbackListener() {
    @Override
    public void onSuccess(JSONObject response) {
        Log.i(TAG, "Search response: " + response.toString());
    }
});

//Search blank request
Personaсlick.search_blank(new Api.OnApiCallbackListener() {
    @Override
    public void onSuccess(JSONObject response) {
        Log.i(T.TAG, "Search response: " + response.toString());
    }
});
const type = 'instant_search';
let search_query = 'your_search_text';
sdk.search({
  type: type,
  search_query: search_query,
  // other params
})
  .then((res) => {
    console.log(res);
  })
  .catch((error) => {
    console.log(error);
  });

HTTP Request

// No implementation is needed in HTTP

Query Parameters

Parameter Required Description
did true Device ID. You get it from init method in SDK.
shop_id true Your API key
sid true Temporary user session ID
type true In this case: "instant_search"
search_query true Search query
locations false Comma separated list of locations IDs
filters_search_by false Available options for filter: name, quantity, popularity

API response

Name Type Description
search_query string Search query
categories array Array with information about categories. Each object has the following properties:
* id – category id (string)
* name – category name (string)
* url – category url (string)
* count – count of products in category (number)
filters array Array with information about filters. Each object has the following properties:
* filter – fitler object. Has the following properties:
* count – total count of products whith this parameters (number)
* values – array of values (object). Has the following properties:
* value – value label. (string)
* count – cont of products whith this parameter (number)
html string HTML-code of the block with products. The template is customized in the PersonaClick personal account.
price_range object Min and max price of products. Has the following properties:
* min – min price (number)
* max – max price (number)
products array Array with information about products. Each object has the following properties:
* description – product description (string)
* url – absolute product URL (string)
* url_handle – relative product URL (string)
* picture – product's picture URL in the PersonaClick storage (string)
* name – product name (string)
* price – product price (number / int)
* price_full – product price (number / float)
* price_formatted – product price with currency (string)
* price_full_formatted – product price with currency (string)
* image_url - absolute product's picture URL in the PersonaClick storage (string)
* image_url_handle - relative product's picture URL in the PersonaClick storage (string)
* image_url_resized - product image resizes url (array)
* currency – product currency (string, corresponds to the currency of the personal account in PersonaClick, or a custom value specified in the shop settings in the personal account)
* id – product ID (string)
* old_price – product old price (number / int, default - 0)
* old_price_full – product old price (number / float)
* old_price_formatted – product old price with currency (string)
* old_price_full_formatted – product old price with currency (string)
Additional properties. If a parameter "extended" is passed in the request
* categories – product categories (array). Has the following properties:
* id – category id (string)
* name – category name (string)
* parent_id – parent category id (string)
* url - category url
* category_ids - product categories ids (array).
search_query_redirects array Array with information about redirects. Each object has the following properties:
* query – search query (string)
* redirect_link – Url for redirect (string)
* deep_link – Url for mobile apps (string)
products_total number Total count of products
book_author array Reserved
book_editor array Reserved
book_publisher array Reserved
book_series array Reserved
book_illustrator array Reserved
book_isbn array Reserved
book_isbn_vars array Reserved
personaclick("search", {search_query: "To be or not to be", page: 2, limit: 15, brands: ["Alas", "poor", "Yorick"], categories: [1, 146, 100500], filters: {'key':['value'], 'key':['value']}, merchants: ['merchant1', 'merchant2'], sort_by: "price", order: "asc"}, function(response) {
  // the functionality of rendering a block of full search
}, function(error) {
  // when something went wrong
});
// Basic full search
sdk.search(query: "iphone") { searchResult in
  print("Full search callback")
}

// Full search with additional parameters
sdk.search(query: "laptop", limit: nil, offset: nil, categoryLimit: nil, categories: nil, extended: nil, sortBy: nil, sortDir: nil, locations: nil, brands: nil, filters: nil, priceMin: nil, priceMax: nil, colors: nil, exclude: nil, fashion_sizes: nil) { searchResult in
  print("Full search callback")
}
//Full search
SearchParams params = new SearchParams();
params.put(SearchParams.Parameter.LOCATIONS, "location");

//Additional filters
SearchParams.SearchFilters filters = new SearchParams.SearchFilters();
filters.put("voltage", new String[] {"11.1", "14.8"});
params.put(SearchParams.Parameter.FILTERS, filters);

//Disable clarification search
params.put(SearchParams.Parameter.NO_CLARIFICATION, true);
Personaсlick.search("SEARCH_QUERY", SearchParams.TYPE.FULL, params, new Api.OnApiCallbackListener() {
    @Override
    public void onSuccess(JSONObject response) {
        Log.i(TAG, "Search response: " + response.toString());
    }
});
const type = 'full_search';
let search_query = 'your_search_text';
sdk.search({
  type,
  search_query,
  // other params
})
  .then((res) => {
    console.log(res);
  })
  .catch((error) => {
    console.log(error);
  });

HTTP Request

GET https://api.personaclick.com/search

Query Parameters

Parameter Required Description
did true Device ID. You get it from init method in SDK.
shop_id true Your API key
sid true Temporary user session ID
type true In this case: "full_search"
search_query true Search query
limit false Limit of results
offset false Offset of results
category_limit false How many categories for sidebar filter to return
categories false Comma separated list of categories to filter
extended false It's better to use true for full search results
sort_by false Sort by parameter: popular, price, discount, sales_rate, date
order false Sort direction: asc or desc (default)
locations false Comma separated list of locations IDs
brands false Comma separated list of brands to filter
filters false Optional escaped JSON string with filter parameters. For example: {"bluetooth":["yes"],"offers":["15% cashback"],"weight":["1.6"]}
price_min false Min price
price_max false Max price
colors false Comma separated list of colors
fashion_sizes false Comma separated list of sizes
exclude false Comma separated list of products IDs to exclude from search results
email false It's only for S2S integration, when service doesn't have user's session. Mobile SDK doesn't use it.
no_clarification false Disable clarified search (true, false, default: false). Don't use it. God mode only.
merchants false Comma separated list of merchants

API response

Name Type Description
brands array Array with information about brands. Each object has the following properties:
* name – brand name (string)
* picture – brand picture (string)
categories array Array with information about categories. Each object has the following properties:
* alias – category alias (string)
* id – category id (string)
* name – category name (string)
* parent – parent category id (string)
* url – category url (string)
filters array Array with information about filters. Each object has the following properties:
* filter – fitler object. Has the following properties:
* count – total count of products whith this parameters (number)
* values – array of values (object). Has the following properties:
* value – value label. (string)
* count – cont of products whith this parameter (number)
industrial_filters array Array with information about industrial filters. For example: colors and fashion_sizes
colors (array of objects) has the following properties: color, count
fashion_sizes (array of objects) has the following properties: size, count
html string HTML-code of the block with products. The template is customized in the PersonaClick personal account.
price_range object Min and max price of products. Has the following properties:
* min – min price (number)
* max – max price (number)
products array Array with information about products. Each object has the following properties:
* brand – product brand (string)
* currency – product currency (string, corresponds to the currency of the personal account in PersonaClick, or a custom value specified in the shop settings in the personal account)
* id – product ID (string)
* is_new – product property (boolean, default - null)
* name – product name (string)
* old_price – product old price (string, default - 0)
* picture – product's picture URL in the PersonaClick storage (string)
* price – product price (number)
* price_formatted – product price with currency (string)
* url – product URL (string)
Additional properties. If a parameter "extended" is passed in the request
* barcode – product barcode (string)
* categories – product categories (array). Has the following properties:
* id – category id (string)
* name – category name (string)
* parent – parent category id (string)
* params – array with information about params. Each object has the following properties:
* key – param name (string)
* values – array of values (array)
products_total number Total count of products
search_query string Search query
book_authors array Reserved
collections array Reserved
keywords array Reserved
queries array Reserved
virtual_categories array Reserved

Search queries with zero results

This method returns a list of queries which return zero results and number of usages of this queries during previous 2 weeks.

For server-to-server integration only.

HTTP Request

GET https://api.personaclick.com/search/no_result_queries

curl https://api.personaclick.com/search/no_result_queries?shop_id=...&shop_secret=...
// No implementation. See CURL
// No implementation. See CURL
// No implementation. See CURL

Response example

[
  {
    "query": "iphone 4s",
    "quantity": 3844
  },
  {
    "contact_type": "covfefe",
    "quantity": 384491
  }
]

Parameters

Parameter Type Required Description
shop_id String true Your API key
shop_secret String true Secret API key

Response properties

Parameter Type Description
query String Search query value
quantity Integer Number of query usages during 2 weeks

Subscriptions

Service provides methods to manage user's subscriptions to email/SMS channels

Manage subscriptions

HTTP Request

POST https://api.personaclick.com/subscriptions/manage

Change user's subscription to different channels and campaigns types


# Full example
curl -d "shop_id=SHOPID&shop_secret=SECRET&[email protected]&phone=+10000000000&email_bulk=true&email_chain=true&email_transactional=true&sms_bulk=true&sms_chain=true&sms_transactional=true" \
https://api.personaclick.com/subscriptions/manage

# Change only specific subscriptions
curl -d "shop_id=SHOPID&shop_secret=SECRET&[email protected]&phone=+10000000000&email_bulk=true&email_chain=true&sms_chain=true&sms_transactional=true" \
https://api.personaclick.com/subscriptions/manage

# Change without phone
curl -d "shop_id=SHOPID&shop_secret=SECRET&[email protected]&email_bulk=true&email_chain=true&sms_chain=true&sms_transactional=true" \
https://api.personaclick.com/subscriptions/manage

# Change without email
curl -d "shop_id=SHOPID&shop_secret=SECRET&phone=+10000000000&email_bulk=true&email_chain=true&sms_chain=true&sms_transactional=true" \
https://api.personaclick.com/subscriptions/manage

# Doesn't work, because there is no identifier
curl -d "shop_id=SHOPID&shop_secret=SECRET&email_bulk=true&email_chain=true&sms_chain=true&sms_transactional=true" \
https://api.personaclick.com/subscriptions/manage

// Subscribe user to all kids of email campaigns and SMS
personaclick('subscription', 'manage', {
    email: '[email protected]',
    phone: '+100000000000',
    email_bulk: true,
    email_chain: true,
    email_transactional: true,
    sms_bulk: true,
    sms_chain: true,
    sms_transactional: true
});

// Change only specific subscriptions
personaclick('subscription', 'manage', {
    email: '[email protected]',
    phone: '+100000000000',
    email_chain: true,
    sms_bulk: true,
    sms_transactional: true
});

// Change without phone
personaclick('subscription', 'manage', {
    email: '[email protected]',
    email_chain: true,
    sms_bulk: true,
    sms_transactional: true
});

// Change without email
personaclick('subscription', 'manage', {
    phone: '+100000000000',
    email_chain: true,
    sms_bulk: true,
    sms_transactional: true
});

// Change by `did` only
personaclick('subscription', 'manage', {
    email_chain: true,
    sms_bulk: true,
});
// With `did` only
sdk.manageSubscription(bulkEmail: true)

// With email and phone
sdk.manageSubscription(email: "[email protected]", phone: "+10000000000", emailBulk: true, smsBulk: true)

// Unsubscribe from bulk SMS and email
sdk.manageSubscription(emailBulk: false, smsBulk: false)

// With everything
sdk.manageSubscription(email: "[email protected]", phone: "+10000000000", userExternalId: "String", userLoyaltyId: "String", telegramId: "String",
  emailBulk: true,
  emailChain: true,
  emailTransactional: true,
  smsBulk: true,
  smsChain: true,
  smsTransactional: true,
  webPushBulk: true,
  webPushChain: true,
  webPushTransactional: true,
  mobilePushBulk: true,
  mobilePushChain: true,
  mobilePushTransactional: true
)
// With `did` only
HashMap<String, Boolean> subscriptions = new HashMap<>();
subscriptions.put("email_bulk", true);
Personaсlick.manageSubscription(null, null, subscriptions);

// With email and phone
HashMap<String, Boolean> subscriptions = new HashMap<>();
subscriptions.put("email_bulk", true);
Personaсlick.manageSubscription("[email protected]", "+10000000000", subscriptions);

// Unsubscribe from bulk SMS and email
HashMap<String, Boolean> subscriptions = new HashMap<>();
subscriptions.put("email_bulk", false);
subscriptions.put("sms_bulk", false);
Personaсlick.manageSubscription(null, null, subscriptions);

The method changes user's subscription to different channels (email, sms) and campaigns types (bulk, chain, transactional).

Parameter Type Required Description
shop_id String true Your API key
shop_secret String true* Secret API key. Required only for REST integration.
email String true* User's email
phone String true* User's email
external_id String true* User's ID from external source
loyalty_id String true* User's loyalty card ID
did String true* Users device ID. It's handled automatically on JS SDK and don't needed in REST API
email_bulk Boolean false Subscribe user to email bulk campaigns
email_chain Boolean false Subscribe user to email drip/trigger campaigns
email_transactional Boolean false Subscribe user to email transactional campaigns
sms_bulk Boolean false Subscribe user to SMS bulk campaigns
sms_chain Boolean false Subscribe user to SMS drip/trigger campaigns
sms_transactional Boolean false Subscribe user to SMS transactional campaigns
web_push_bulk Boolean false Subscribe user to Web push bulk campaigns
web_push_chain Boolean false Subscribe user to Web push drip/trigger campaigns
web_push_transactional Boolean false Subscribe user to Web push transactional campaigns
mobile_push_bulk Boolean false Subscribe user to Mobile push bulk campaigns
mobile_push_chain Boolean false Subscribe user to Mobile push drip/trigger campaigns
mobile_push_transactional Boolean false Subscribe user to Mobile push transactional campaigns

System operations: unsubscribe, complaint, hard bounce and blacklist

This method is used to mark email with specific status.

POST https://api.personaclick.com/subscriptions/callback

Email is bounced

Use this method only for hard bounces. Don't use it for soft bounce, because it purges email from database forever.

curl -d "shop_id=SHOPID&shop_secret=SECRET&[email protected]&event=hard_bounced" \
https://api.personaclick.com/subscriptions/callback

# Response:
{"status":  "success"}
// No implementation. See CURL
// No implementation. See CURL
// No implementation. See CURL
Parameter Type Required Description
shop_id String true Your API key
shop_secret String true Secret API key. Required only for REST integration.
email String true User's email
event String true Event to process: hard_bounced

Email is complained

Use this method on FBL request (user marked email as spam):

curl -d "shop_id=SHOPID&shop_secret=SECRET&[email protected]&event=complained" \
https://api.personaclick.com/subscriptions/callback

# Response:
{"status":  "success"}
// No implementation. See CURL
// No implementation. See CURL
// No implementation. See CURL
Parameter Type Required Description
shop_id String true Your API key
shop_secret String true Secret API key. Required only for REST integration.
email String true User's email
event String true Event to process: complained

Email is blacklisted

Use this method to add email to black list:

curl -d "shop_id=SHOPID&shop_secret=SECRET&[email protected]&event=blacklisted" \
https://api.personaclick.com/subscriptions/callback

# Response:
{"status":  "success"}
// No implementation. See CURL
// No implementation. See CURL
// No implementation. See CURL
Parameter Type Required Description
shop_id String true Your API key
shop_secret String true Secret API key. Required only for REST integration.
email String true User's email
event String true Event to process: blacklisted

Email is unsubscribed

Use this method to unsubscribe email:

curl -d "shop_id=SHOPID&shop_secret=SECRET&[email protected]&event=unsubscribed" \
https://api.personaclick.com/subscriptions/callback

# Response:
{"status":  "success"}
// No implementation. See CURL
// No implementation. See CURL
// No implementation. See CURL
Parameter Type Required Description
shop_id String true Your API key
shop_secret String true Secret API key. Required only for REST integration.
email String true User's email
event String true Event to process: unsubscribed

Check subscription status

GET https://api.personaclick.com/subscriptions/check

curl https://api.personaclick.com/subscriptions/check
personaclick('subscription', 'check',
function (subscriptions) {
  console.log(subscriptions)
},
function(error) {
  console.log(error)
});
// No implementation. See CURL
// No implementation. See CURL

Response example

{
    "exists": false,
    "email_bulk": false,
    "email_chain": false,
    "email_transactional": false,
    "email_invalid": false,
    "email_blacklisted": false,
    "email_bounced": false,
    "email_suppressed": false,
    "email_confirmed": false,
    "web_push_bulk": false,
    "web_push_chain": false,
    "web_push_transactional": false,
    "mobile_push_bulk": false,
    "mobile_push_chain": false,
    "mobile_push_transactional": false,
    "sms_bulk": false,
    "sms_chain": false,
    "sms_transactional": false
}

Checks email's subscription status.

Parameter Type Required Description
shop_id String true Your API key
shop_secret String true** Secret API key. Can be sent as header X-Shop-Secret.
email String true* User's email
phone String true* User's phone.
did String true* User's did.

Response flags:

Property Type Description
exists Boolean Check if user with specified contact is present in CDP
email_bulk Boolean Email is subscribed to bulk emails
email_chain Boolean Email is subscribed to drip campaigns (triggers)
email_transactional Boolean Email is subscribed to transactional emails
email_invalid Boolean Email is invalid or disposal email
email_blacklisted Boolean Email is blacklisted (spam trap, etc)
email_bounced Boolean Email is hard bounced
email_suppressed Boolean Email is suppressed due to complaint
email_confirmed Boolean Email is confirmed by DOI
web_push_bulk Boolean User has phone and subscribed to bulk Web push campaigns
web_push_chain Boolean User has phone and subscribed to drip Web push campaigns (triggers)
web_push_transactional Boolean User has phone and subscribed to transactional Web push campaigns
mobile_push_bulk Boolean User has phone and subscribed to bulk Mobile push campaigns
mobile_push_chain Boolean User has phone and subscribed to drip Mobile push campaigns (triggers)
mobile_push_transactional Boolean User has phone and subscribed to transactional Mobile push campaigns
sms_bulk Boolean User has phone and subscribed to bulk SMS campaigns
sms_chain Boolean User has phone and subscribed to drip SMS campaigns (triggers)
sms_transactional Boolean User has phone and subscribed to transactional SMS campaigns

Changed subscriptions list

This method returns users with changed subscriptions statuses during defined dates range (default 24 hours).

Returns an array of users with email or/and phone, who changed subscriptions status during last 24 hours. Sorted by time ascending.

GET https://api.personaclick.com/subscriptions/changes

curl https://api.personaclick.com/subscriptions/changes?shop_id=...&shop_secret=...
// No implementation. See CURL
// No implementation. See CURL
// No implementation. See CURL

Response example

[
  {
    "contact_type": "email",
    "contact": "[email protected]",
    "campaign_type": "chain",
    "event": "subscribe",
    "channel": "popup",
    "datetime": "2020-09-24 14:42:36",
    "ip": "192.168.0.1"
  },
  {
    "contact_type": "email",
    "contact": "[email protected]",
    "campaign_type": "bulk",
    "event": "unsubscribe",
    "channel": "unsubscribe_page",
    "datetime": "2020-09-23 14:43:36",
    "ip": "192.168.2.27"
  },
  {
    "contact_type": "email",
    "contact": "[email protected]",
    "campaign_type": "bulk",
    "event": "hard_bounced",
    "channel": "email_processing",
    "datetime": "2020-09-23 14:43:36",
    "ip": "192.168.2.27"
  },
  {
    "contact_type": "sms",
    "contact": "+19990009999",
    "campaign_type": "transactional",
    "event": "subscribe",
    "channel": "crm",
    "datetime": "2020-09-25 14:43:36",
    "ip": "192.168.2.27"
  }
]

Parameters

Parameter Type Required Description
shop_id String true Your API key.
shop_secret String true Secret API key. Can be sent as header X-Shop-Secret.
event String false Filter by event.
channel String false Filter by channel.
from String false Date from in YYYY-MM-DD format. Default value: 1 day ago.
to String false Date to in YYYY-MM-DD format. Default value: current date.
email String false Find only logs with specified email.
phone String false Find only logs with specified phone.
offset Integer false Offset from the beginning of the selected dataset. Min: 0.
limit Integer false Limit of the returned dataset size. Max: 20000.

Response properties

Parameter Type Description
contact_type String Type of contact: sms, email, mpush, wpush
contact String Contact value
campaign_type String Type of campaigns: bulk, chain, transactional, everything
event String Type of event: subscribe, unsubscribe, hard_bounced, complained, blacklisted
channel String Channel of event: api, js_sdk, unsubscribe_page, email_processing, etc
datetime String Date and time in YYYY-MM-DD H:i:s format
ip String IP from where request was received. Can be empty for some kinds of channel parameter.

Event descriptions:

Event Description
subscribe User is subscribed for messages (email, sms)
unsubscribe User is unsubscribed
hard_bounced User's contact is hard bounced (not existing email, phone)
complained User is complained (FBL). As result: unsubscribed and suppressed
blacklisted User is blacklisted

Channel descriptions

Event Description
email_feedback_processing Mailing feedback processing (FBL, bounce worker, automatic unsubscribe)
api Log from subscriptions/manage method
api_callback Log from subscriptions/callback method
js_sdk Event from JS SDK. Reserved
mobile_sdk Event from Mobile SDK. Reserved
push_attributes Event from event/push_attributes method. Deprecated
auto_collector Event from auto_collector service
popup Subscription from pop-up
import Subscription from audience import
crm Subscription management in CRM UI
bulk_sending Automatic bounce worker while sending bulk mailing
transactional_sending Automatic bounce worker while sending transactional mailing
unsubscribe_page User clicked on "unsubscribe" link in email sent by PersonaClick
resubscribe_page User clicked on "re-subscribe" link on PersonaClick's "unsubscribe" page

Triggers

Trigger subscription methods that require explicit user action.

Price drop

# Subscribing
curl --location --request POST 'https://api.personaclick.com/subscriptions/subscribe_for_product_price' \
--header 'Content-Type: application/json' \
--data-raw '{
    "shop_id":"SHOP_ID",
    "email":"EMAIL",
    "phone":"PHONE",
    "did":"DeviceID",
    "item_id":"11111",
    "price": "1000"
}'

# Unsubscribing from specific products
curl --location --request POST 'https://api.personaclick.com/subscriptions/unsubscribe_from_product_price' \
--header 'Content-Type: application/json' \
--data-raw '{
    "shop_id":"SHOP_ID",
    "email":"EMAIL",
    "phone":"PHONE",
    "did":"DeviceID",
    "item_ids":"11111, 22222, 333333"
}'

# Unsubscribing from all products
curl --location --request POST 'https://api.personaclick.com/subscriptions/unsubscribe_from_product_price' \
--header 'Content-Type: application/json' \
--data-raw '{
    "shop_id":"SHOP_ID",
    "email":"EMAIL",
    "phone":"PHONE",
    "did":"DeviceID",
    "item_ids":""
}'
// Subscribing
personaclick('subscribe_trigger', 'product_price_decrease', {email: '[email protected]', item: '3323', price: 160});

// Unsubscribing from specific products
personaclick('unsubscribe_trigger', 'product_price_decrease', {email: '[email protected]', item_ids: [3323, 100500, 'ABCDEF']});

// Unsubscribing from all products
personaclick('unsubscribe_trigger', 'product_price_decrease', {email: '[email protected]', item_ids: []});
// Subscribe
sdk.subscribeForPriceDrop(id: "PRODUCT_ID", currentPrice: 333.49);

// Subscribe for specific email
sdk.subscribeForPriceDrop(id: "PRODUCT_ID", currentPrice: 333.49, email: "[email protected]");

// Subscribe for specific phone
sdk.subscribeForPriceDrop(id: "PRODUCT_ID", currentPrice: 333.49, phone: "+19999999999");
// Subscribe
Personaсlick.subscribeForPriceDrop("PRODUCT_ID", 333.49);

// Subscribe for specific email
Personaсlick.subscribeForPriceDrop("PRODUCT_ID", 333.49, "[email protected]");

// Subscribe for specific phone
Personaсlick.subscribeForPriceDrop("PRODUCT_ID", 333.49, null, "+19999999999");

// Unsubscribing from specific products
Personaсlick.unsubscribeForPriceDrop(new String[] {"11111", "22222", "33333"});

// Unsubscribing from all products
Personaсlick.unsubscribeForPriceDrop(new String[] {});

This feature gives the customers an option to choose if they want to receive a notification when the price of the item they want has dropped.

JS SDK syntax

Syntax
personaclick('subscribe_trigger', 'product_price_decrease', params);

JS SDK Parameters

Parameter Type Requirement Description
email* string required Subscriber Email
phone* string required Subscriber Phone
did* string required Subscriber Did
item number/string required The ID of the product to which the user will be subscribed
price number/string required The current product price

JS SDK syntax

Syntax
personaclick('unsubscribe_trigger', 'product_price_decrease', params);

JS SDK Parameters

Parameter Type Requirement Description
email* string required Subscriber Email
phone* string required Subscriber Phone
did* string required Subscriber Did
item_ids array required The IDs of the products from which the user will unsubscribe, or an empty array for full unsubscription

Back in Stock

# Subscribing
curl --location --request POST 'https://api.personaclick.com/subscriptions/subscribe_for_product_available' \
--header 'Content-Type: application/json' \
--data-raw '{
    "shop_id":"SHOP_ID",
    "email":"EMAIL",
    "item_id":"11111",
    "phone":"PHONE",
    "did":"DeviceID",
    "properties": {"fashion_size":"XL", "barcode": "222222"}
}'

# Unsubscribing from specific products
curl --location --request POST 'https://api.personaclick.com/subscriptions/unsubscribe_from_product_available' \
--header 'Content-Type: application/json' \
--data-raw '{
    "shop_id":"SHOP_ID",
    "email":"EMAIL",
    "phone":"PHONE",
    "did":"DeviceID",
    "item_ids":"11111, 22222, 333333"
}'

# Unsubscribing from all products
curl --location --request POST 'https://api.personaclick.com/subscriptions/unsubscribe_from_product_available' \
--header 'Content-Type: application/json' \
--data-raw '{
    "shop_id":"SHOP_ID",
    "email":"EMAIL",
    "phone":"PHONE",
    "did":"DeviceID",
    "item_ids":""
}'
// Subscribing
personaclick('subscribe_trigger', 'product_available', {email: '[email protected]', item: '3323', properties: {fashion_size: "XL", barcode: "222222"}});

// Unsubscribing from specific products
personaclick('unsubscribe_trigger', 'product_available', {email: '[email protected]', item_ids: [3323, 100500, 'ABCDEF']});

// Unsubscribing from all products
personaclick('unsubscribe_trigger', 'product_available', {email: '[email protected]', item_ids: []});
// Subscribe
sdk.subscribeForBackInStock(id: "PRODUCT_ID");

// Subscribe for specific email
sdk.subscribeForBackInStock(id: "PRODUCT_ID", email: "[email protected]");

// Subscribe for specific phone
sdk.subscribeForBackInStock(id: "PRODUCT_ID", phone: "+19999999999");
// Subscribe
Personaсlick.subscribeForBackInStock("PRODUCT_ID");

// Subscribe for specific email
Personaсlick.subscribeForBackInStock("PRODUCT_ID", "[email protected]");

// Subscribe for specific phone
Personaсlick.subscribeForBackInStock("PRODUCT_ID", "+19999999999");

// Subscribe with product size
JSONObject properties = new JSONObject();
properties.put("fashion_size", "XL");
Personaсlick.subscribeForBackInStock("PRODUCT_ID", properties, "[email protected]", null, null);

// Unsubscribing from specific products
Personaсlick.unsubscribeForBackInStock(new String[] {"11111", "22222", "33333"});

// Unsubscribing from all products
Personaсlick.unsubscribeForBackInStock(new String[] {});
// Subscribing
PersonaClick.triggers('subscribe_for_product_available', {email: '[email protected]', item: '3323', properties: {fashion_size: "XL"}});

// Unsubscribing from specific products
PersonaClick.triggers('unsubscribe_from_product_available', {email: '[email protected]', item_ids: [3323, 100500, 'ABCDEF']});

// Unsubscribing from all products
PersonaClick.triggers('unsubscribe_from_product_available', {email: '[email protected]', item_ids: []});

This feature helps you recover sales lost due to out-of-stock items by giving your customers an option to choose if they want to receive a notification when the item they want is back in stock.

JS SDK syntax

Syntax
personaclick('subscribe_trigger', 'product_available', params);

JS SDK Parameters

Parameter Type Requirement Description
email* string required Subscriber Email
phone* string required Subscriber Phone
did* string required Subscriber Did
item number/string required The ID of the product to which the user will be subscribed
params object optional Product properties: barcode, fashion_color, fashion_size

JS SDK syntax

Syntax
personaclick('unsubscribe_trigger', 'product_available', params);

JS SDK Parameters

Parameter Type Requirement Description
email* string required Subscriber Email
phone* string required Subscriber Phone
did* string required Subscriber Did
item_ids array required The IDs of the products from which the user will unsubscribe, or an empty array for full unsubscription

Transactionals

The method allows you to send transactional messages.

Request transactionals

# Request with JSON
curl --location --request POST 'https://api.personaclick.com/transact' \
--header 'Content-Type: application/json' \
--data-raw '"shop_id":"SHOP_ID", "shop_secret":"SHOP_SECRET", "code":"TRANSACTIONAL_MESSAGE_CODE", "email":"EMAIL", "variables":{"KEY":"VALUE", "KEY_2":"VALUE_2"}}'

# Request with FormData
curl --location --request POST 'https://api.personaclick.com/transact' \
--form 'file_name=@"local_file_path/local_file_name"' \
--form 'file_name_2=@"local_file_path/local_file_name_2"' \
--form 'shop_id="SHOP_ID"' \
--form 'shop_secret="SHOP_SECRET"' \
--form 'code="TRANSACTIONAL_MESSAGE_CODE"' \
--form 'email="EMAIL"' \
--form 'variables[KEY]="VALUE"'
--form 'variables[KEY_2]="VALUE_2"'
// REST API only. See cURL.
// REST API only. See cURL.
// REST API only. See cURL.
// REST API only. See cURL.

HTTP Request

GET https://api.personaclick.com/transact

Query Parameters

Parameter Required Description
shop_id true Your shop id
shop_secret true Your shop secret
code true Your transactional message code
email true Client's email
variables false Object with custom data for message

HTTP Response

HTTP status code Response body Explanation
204 none The request was successful.
4xx (400-499) {"status": "error", "message": "Error description text"} The request was unsuccessful. See the reason in the message property of the response body.

Mobile push tokens

Create new token

curl -d "did=DEVICE_ID&shop_id=SHOPID&token=TOKEN&platform=PLATFORM" https://api.personaclick.com/mobile_push_tokens
sdk.setPushTokenNotification(token: "TOKEN_STRING") { (tokenResponse) in
  print("Token set response")
}
Personaсlick.setPushTokenNotification("token", new Api.OnApiCallbackListener() {
    @Override
    public void onSuccess(JSONObject msg) {
        //
    }
});
// When you request permissions to send notifications and receive push token,
// send it to API using this method:
sdk.setPushTokenNotification('NEW_TOKEN');

The above command returns JSON structured like this:

{}

This endpoint creates new token for the user, identified by did parameter.

HTTP Request

POST https://api.personaclick.com/mobile_push_tokens

Query Parameters

Parameter Required Description
did true Device ID. You get it from init method in SDK.
platform true Identifies platform: ios for APNs or android for Firebase
token true Unique mobile push token from iOS or Android.
shop_id true Your API key

Sending mobile push notifications

// Simple init
sdk.initPush();

//onClick listener
sdk.initPush(onClickCallback);

// onReceivetive listener
sdk.initPush(false, onReceiveCallback);

// you can use different callback for notification, when app is in background.
sdk.initPush(false, onReceiveCallback, onBackgroundReceiveCallback);

// If onBackgroundReceiveCallback not specified, used onReceiveCallback listener.

// onClickCallback params
{
  "bigPictureUrl": "MESSAGE_IMAGE",
  "channelId": "personaclick-push",
  "data": {
    "id": "MESSAGE_ID",
    "type": "MESSAGE_TYPE"
  },
  "foreground": true,
  "id": "MESSAGE_ID",
  "largeIconUrl": "MESSAGE_ICON",
  "message": "MESSAGE_BODY",
  "title": "MESSAGE_TITLE",
  "userInteraction": true
}
// onReceiveCallBack, onBackgroundReceiveCallback params
{
  "data": {
    "action_urls": "[]",
    "actions": "[]",
    "body": "MESSAGE_BODY",
    "icon": "MESSAGE_ICON",
    "id": "MESSAGE_ID",
    "image": "MESSAGE_IMAGE",
    "title": "MESSAGE_TITLE",
    "type": "MESSAGE_TYPE"
  },
  "from": "MESSAGE_FROM",
  "messageId": "FMC_MESSAGE_ID",
  "sentTime": TIMESTAMP,
  "ttl": TTL_VALUE
}

Default payload structure

For iOS

{
  "aps": {
    "alert": {
      "title": "...",
      "subtitle": "...",
      "body": "...",
      "badge": 1
    },
    "mutable-content": 1
  },
  "image_url": "...",
  "event": {
    "type": "...",
    "uri": "..."
  },
  "src": {
    "type": "...",
    "id": "..."
  }
}

For Android

{
  "title": "...",
  "body": "...",
  "icon": "...",
  "type": "...",
  "id": "...",
  "actions": "[{\"action\": "\b0\", \"title\": \"...\"}, ...]",
  "action_urls": "[...]",
  "image": "...",
  "event": "{\"type\": \"...\", \"uri\": \"...\"}"
}
Parameter Required Description
aps.alert.title true The title of the notification. Apple Watch displays this string in the short look notification interface. Specify a string that is quickly understood by the user.
aps.alert.subtitle true Additional information that explains the purpose of the notification.
aps.alert.body true The content of the alert message.
aps.alert.badge true The number to display in a badge on your app’s icon. Specify 0 to remove the current badge, if any.
aps.mutable-content true Always 1 for iOS.
image_url false Link to image/icon.
event false Optional object with additional data.
event.type true Type of the notification: web, category, product, custom.
event.uri true Resource identificator depending on the type of event. See examples below.
src true Information about a campaign (source of the message).
src.type true Type of a campaign: bulk, chain, transactional.
src.id true Type of a campaign. String.

Basic message

For iOS

{
  "aps": {
    "alert": {
      "title": "Welcome aboard!",
      "subtitle": "Greeting message.",
      "body": "Hey, it's nice to know you're with us now. Check new updates in our application.",
      "badge": 1
    },
    "mutable-content": 1
  },
  "image_url": "...",
  "src": {
    "type": "bulk",
    "id": "33631"
  }
}

For Android

{
  "title": "Welcome aboard!",
  "body": "Hey, it's nice to know you're with us now. Check new updates in our application.",
  "icon": "...",
  "type": "bulk",
  "id": "33631"
}

This kind of message can be used to attract attention and open home screen of the application.

For iOS

{
  "aps": {
    "alert": {
      "title": "Only today",
      "subtitle": "Special Offer",
      "body": "This special offer for Dyson products only for you!",
      "badge": 1
    },
    "mutable-content": 1
  },
  "image_url": "...",
  "event": {
    "type": "web",
    "uri": "https://example.com/landing/promo"
  },
  "src": {
    "type": "bulk",
    "id": "XFMjM4VAF4"
  }
}

For Android

{
  "title": "Only today",
  "body": "This special offer for Dyson products only for you!",
  "icon": "...",
  "type": "bulk",
  "id": "XFMjM4VAF4",
  "event": "{\"type\": \"web\", \"uri\": \"https://example.com/landing/promo\"}"
}

Usually used for promo campaigns when final action is to open some URL in web view.

Open category

For iOS

{
  "aps": {
    "alert": {
      "title": "Black Friday!",
      "subtitle": "Discount",
      "body": "Check our big sale from this category",
      "badge": 1
    },
    "mutable-content": 1
  },
  "image_url": "...",
  "event": {
    "type": "category",
    "uri": "BFRIDAY_CATEGORY_ID"
  },
  "src": {
    "type": "chain",
    "id": "72CONd54uF"
  }
}

For Android

{
  "title": "Black Friday!",
  "body": "Check our big sale from this category",
  "icon": "...",
  "type": "chain",
  "id": "72CONd54uF",
  "event": "{\"type\": \"category\", \"uri\": \"BFRIDAY_CATEGORY_ID\"}"
}

Suitable to open specific category by it's ID. For example for bulk messages about discounts.

Open product

For iOS

{
  "aps": {
    "alert": {
      "title": "...",
      "subtitle": "...",
      "body": "...",
      "badge": 1
    },
    "mutable-content": 1
  },
  "image_url": "...",
  "event": {
    "type": "product",
    "uri": "PRODUCT123"
  },
  "src": {
    "type": "chain",
    "id": "ugLxQ7KrnL"
  }
}

For Android

{
  "title": "...",
  "body": "...",
  "icon": "...",
  "type": "chain",
  "id": "ugLxQ7KrnL",
  "event": "{\"type\": \"product\", \"uri\": \"PRODUCT123\"}"
}

Suitable to open specific product by it's ID. For example for triggered messages.

Open custom page

For iOS

{
  "aps": {
    "alert": {
      "title": "...",
      "subtitle": "...",
      "body": "...",
      "badge": 1
    },
    "mutable-content": 1
  },
  "image_url": "...",
  "event": {
    "type": "custom",
    "uri": "order/status/36",
    "payload": {}
  },
  "src": {
    "type": "transactional",
    "id": "order_delivered"
  }
}

For Android

{
  "title": "...",
  "body": "...",
  "type": "transactional",
  "id": "order_delivered",
  "event": "{\"type\": \"custom\", \"uri\": \"order/status/36\", \"payload\": {}}"
}

Can be used to open any resource by custom data. For example for transactional messages to show order status.

User's profile

Endpoints is used to work with user's profile.

Save profile settings

curl -d "shop_id=SHOPID&shop_secret=SHOP_SECRET&email=EMAIL&fieldname=FIELDVALUE" https://api.personaclick.com/profile/set
personaclick('profile', 'set', {
    "email": "[email protected]",
    "id": "123456789",
    "loyalty_id": "987654321",
    "phone": "19991005000",
    "first_name": "Jane",
    "last_name": "Smith",
    "location": "sdsdfsdfsdf",
    "kids": [
        {"gender": "m", "birthday": "2017-06-04"},
        {"gender": "f", "birthday": "2014-02-10"},
        {"gender": "m", "birthday": "2014-03-17"}
    ]
});
//An example of using custom fields by type
personaclick('profile', 'set', {
    "string": "sdsdfsdfsdf",
    "int": 123,
    "float": 123.12,
    "list_element": ["first", "second"],
    "json": {"key": "val", "key2": "val2"},
    "date": "2022-08-26"
});
  sdk.setProfileData(userEmail: 'email@example.com',
    userPhone: '10000000000',
    userLoyaltyId: 'L010101',
    birthday: ...,
    age: ...,
    firstName: ...,
    lastName: ...,
    location: ...,
    gender: ...) { (profileDataResp) in
      print("Profile data callback")
    }
  HashMap<String, String> params = new HashMap<>();
  params.put("email", "[email protected]");
  Personaсlick.profile(params);
  //With callback
  Personaсlick.profile(params, new Api.OnApiCallbackListener() {
      @Override
      public void onSuccess(JSONObject response) {
          Log.i(TAG, "Response: " + response.toString());
      }
  });
const params = {
  id: 100500,
  email: "[email protected]",
  phone: "4400114527199",
  first_name: "John",
  last_name: "Doe",
  birthday: "1990-03-11",
  age: 31,
  gender: "m",
  location: "NY",
  bought_something: true,
  loyalty_id: "000001234567",
  loyalty_card_location: "NY",
  loyalty_status: "5% discount",
  loyalty_bonuses: 1123,
  loyalty_bonuses_to_next_level: 1877,
  fb_id: "000000000354677",
  vk_id: "vk031845",
  telegram_id: "0125762968357835",
  kids: [
    {gender: "m", birthday: "2001-04-12"},
    {gender: "f", birthday: "2015-07-28"}
  ],
  auto: [
    {brand: "Nissan", model: "Qashqai", vds: "TM7N243E4G0BJG978"}
  ]
};

sdk.setProfile(params);

This method overrides profile's settings.

Query Parameters

Parameter Type Required Description
shop_id String true Your API key
shop_secret String true Your API secret key
did* String true Device ID
email* String true User's email
phone* String true User's phone number

Default properties

You can update any standard profile property. All standard properties are listed here:

Parameter Type Description
loyalty_id String User's loyalty program ID
id String User ID in your platform
fb_id String User's Facebook ID
vk_id String User's VK ID
telegram_id String User's Telegram ID
loyalty_card_location String Location ID where user's loyalty card was issued
loyalty_status String User's loyalty program status
loyalty_bonuses Integer User's bonuses amount
loyalty_bonuses_to_next_level Integer User's bonuses amount left for the next level
gender String User's gender: m or f
location String User's location code
first_name String User's first name
last_name String User's last name
age Integer User's age in years
birthday Date User's birthday in SQL format: YYYY-MM-DD
bought_something Bool User bought something ever
kids Array List of kids (see below)
auto Array List of auto vehicles (see below)

Kid object properties:

Parameter Type Description
gender String Kid's gender: m or f
birthday Date Kid's birthday in SQL format: YYYY-MM-DD

Auto object properties:

Parameter Type Description
brand String Vehicle brand
model String Vehicle model
vds String Vehicle VDS/VIN number

Custom properties

Additionally you can update any custom property, you've created in CRM.

Read profile info

# Using email as user identifier
curl https://api.personaclick.com/profile?email=...&shop_id=...&shop_secret=...

# Using phone as user identifier
curl https://api.personaclick.com/profile?phone=...&shop_id=...&shop_secret=...
personaclick('profile', 'get', function(profile) {
    // Here you can use all properties of profile's object
    console.log(profile.gender);
    console.log(profile.fashion.sizes.shoe);
},
// Use `true`, to work in single page sites.
// Default - `false`
false
);

REST method returns this JSON structure

{
  "first_name": "...",
  "last_name": "...",
  "email": "...",
  "phone": "...",
  "fb_id": "...",
  "vk_id": "...",
  "telegram_id": "...",
  "loyalty_id": "...",
  "loyalty_card_location": "...",
  "loyalty_status": "...",
  "loyalty_bonuses": "...",
  "loyalty_bonuses_to_next_level": "...",
  "gender": "...",
  "location": "...",
  "age": "...",
  "birthday": "...",
  "bought_something": "...",
  "tags": [
    "...",
    "..."
  ],
  "custom_properties": {
    "prop_key_1": "prop_value",
    "prop_key_2": "prop_value"
  },
  "additional_phones": [],
  "additional_emails": [],
  "additional_loyalty_ids": [],
  "orders": [
    {
      "id": "...",
      "value": "...",
      "status": "...",
      "items": [
        {
          "id": "...",
          "price": "...",
          "name": "...",
          "quantity": "..."
        },
        {
          "id": "...",
          "price": "...",
          "name": "...",
          "quantity": "..."
        }
      ]
    }
  ]
}

JS SDK method returns simplified anonymous structure to prevent data stealing

{
  "fashion_sizes": ["..."],

  "gender": "m or f",

  "cosmetic_hair": ["..."],
  "allergy": "bool",
  "cosmetic_skin": ["..."],
  "cosmetic_perfume": ["..."],

  "compatibility": null,
  "vds": null,

  "jewelry": null,

  "realty": ["..."],

  "children": ["..."],
  "child_gender": "m or f",

  "pets": ["..."],

  "income_level": "cheap"
}

You can read profile info from CRM using API or SDK.

In case of using REST API (when using email or phone number as user ID), you must provide secret key to the method.

Force change email

curl -d "shop_id=SHOPID&shop_secret=SHOP_SECRET&new_email=NEW_EMAIL&old_email=OLD_EMAIL" https://api.personaclick.com/profile/force_change_email
// Not supported
// Not supported
// Not supported
// Not supported

Force change email of user with old_email to new_email. If a user with new_email exists, removes email from that user.

If user with old_email is not found, returns 404.

It's S2S method.

Query Parameters

Parameter Type Required Description
shop_id String true Your API key
shop_secret String true Your API secret key
new_email String true User's new email
old_email String true User's current email
i_understand_what_i_am_doing String true Must present with any true value (true, "true", 1, yes, believe me I know what I am doing, etc).

Force change phone

curl -d "shop_id=SHOPID&shop_secret=SHOP_SECRET&new_phone=NEW_PHONE&old_phone=OLD_PHONE" https://api.personaclick.com/profile/force_change_phone
// Not supported
// Not supported
// Not supported
// Not supported

Force change phone of user with old_phone to new_phone. If a user with new_phone exists, removes phone from that user.

If user with old_phone is not found, returns 404.

It's S2S method.

Query Parameters

Parameter Type Required Description
shop_id String true Your API key
shop_secret String true Your API secret key
new_phone String true User's new phone
old_phone String true User's current phone
i_understand_what_i_am_doing String true Must present with any true value (true, "true", 1, yes, believe me I know what I am doing, etc).

Audience

This section allows to manage users, their subscriptions and segments.

Import users

curl -i -X POST -H "Content-Type: application/json" --data-binary "@data.json" https://api.personaclick.com/import/audience

# data.json
{
  "shop_id": "1234567890",
  "shop_secret": "0987654321",
  "segment_id": "123",
  "audience": [
    {
      "email": "[email protected]",
      "loyalty_id": "123454321",
      "phone": "19991005000",
      "id": "998877",
      "fb_id": "",
      "vk_id": "",
      "telegram_id": "",
      "loyalty_card_location": "",
      "loyalty_status": "VIP",
      "loyalty_bonuses": 3000,
      "loyalty_bonuses_to_next_level": 70000,
      "gender": "",
      "location": "",
      "first_name": "Jane",
      "last_name": "Smith",
      "age": "",
      "birthday": "",
      "bought_something": true,
      "email_bulk": true,
      "email_chain": true,
      "email_transactional": true,
      "sms_bulk": true,
      "sms_chain": true,
      "sms_transactional": true,
      "mobile_token": "TOKEN",
      "mobile_token_platform": "PLATFORM",
      "auto": [
        {
          "brand": "Mini",
          "model": "Countryman",
          "vds": "1234567"
        },
        {
          "brand": "Toyota",
          "model": "Corolla",
          "vds": "987655431"
        }
      ],
      "kids": [
        {
          "birthday": "2014-06-03",
          "gender": "f"
          },
        {
          "birthday": "2017-04-01",
          "gender": "m"
        }
      ],

    },
    {...},
    {...},
  ]
}
// No implementation is needed in JS SDK
// No implementation is needed in iOS SDK
// No implementation is needed in Android SDK

Upload audience to database. You can upload users to the default segment or put it in the specific segment. At the same time you can subscribe or unsubscribe users from any kind of email campaigns.

Query Parameters

Parameter Type Required Description
shop_id String true Your API key
shop_secret String true Your API secret key
segment_id Integer false Segment ID
audience Array true Array of user data objects (see below)

Audience element properties

You can update any standard profile property. All standard properties are listed here:

Parameter Type Description
email* String User's email
phone* String User's phone number
loyalty_id String User's loyalty program ID
id String User ID in your platform
fb_id String User's Facebook ID
vk_id String User's VK ID
telegram_id String User's Telegram ID
loyalty_card_location String Location ID where user's loyalty card was issued
loyalty_status String User's loyalty program status
loyalty_bonuses Integer User's bonuses amount
loyalty_bonuses_to_next_level Integer User's bonuses amount left for the next level
gender String User's gender: m or f
location String User's location code
first_name String User's first name
last_name String User's last name
age Integer User's age in years
birthday Date User's birthday in SQL format: YYYY-MM-DD
bought_something Bool User bought something ever
kids Array List of kids (see below)
auto Array List of auto vehicles (see below)
email_bulk Boolean Subscribe user to email bulk campaigns
email_chain Boolean Subscribe user to email drip/trigger campaigns
email_transactional Boolean Subscribe user to email transactional campaigns
sms_bulk Boolean Subscribe user to SMS bulk campaigns
sms_chain Boolean Subscribe user to SMS drip/trigger campaigns
sms_transactional Boolean Subscribe user to SMS transactional campaigns
mobile_token String Unique mobile push token from iOS or Android
mobile_token_platform String Identifies platform: ios for APNs or android for Firebase

Kid object properties:

Parameter Type Description
gender String Kid's gender: m or f
birthday Date Kid's birthday in SQL format: YYYY-MM-DD

Auto object properties:

Parameter Type Description
brand String Vehicle brand
model String Vehicle model
vds String Vehicle VDS/VIN number

Custom properties

Additionally you can update any custom property, you've created in CRM.

Import suppressed emails

curl -i -X POST -H "Content-Type: application/json" --data-binary "@data.json" https://api.personaclick.com/import/suppressed

# data.json
{
  "shop_id": "1234567890",
  "shop_secret": "0987654321",
  "audience": [
    { "email": "[email protected]" },
    { "email": "[email protected]" },
  ]
}
// No implementation is needed in JS SDK
// No implementation is needed in iOS SDK
// No implementation is needed in Android SDK

Upload suppressed emails to database. All emails from this list will be unsubscribed from emails and marked as suppressed.

Query Parameters

Parameter Type Required Description
shop_id String true Your API key
shop_secret String true Your API secret key
audience Array true Array of user data objects (see below)

Audience element properties

Parameter Type Description
email String User's email

CRM

This section collects CRM-related methods.

Bulk search by attribute

curl -i -X POST -H "Content-Type: application/json" --data-binary "@data.json" https://api.personaclick.com/crm/search/bulk

# data.json
{
  "shop_id": "1234567890",
  "shop_secret": "0987654321",
  "by": "loyalty_id",
  "ids": ["L01", "L02"]
}
// No implementation is needed in JS SDK
// No implementation is needed in iOS SDK
// No implementation is needed in Android SDK

Response structure

[
  {
    "email": "[email protected]",
    "external_id": "1",
    "phone": "11111111111",
    "first_name": null,
    "last_name": null,
    "gender": null,
    "age": null,
    "birthday": null,
    "location": null,
    "email_bulk": true,
    "email_chain": true,
    "email_transactional": true,
    "web_push": true,
    "mobile_push": null,
    "sms_bulk": null,
    "sms_chain": null,
    "sms_transactional": null,
    "loyalty_id": "L01",
    "loyalty_location": null,
    "loyalty_status": null,
    "loyalty_bonuses": 300,
    "loyalty_bonuses_to_next_level": null,
    "created_date": null,
    "device": null
  },
  {
    "email": "[email protected]",
    "external_id": "1",
    "phone": null,
    "first_name": "Thomas",
    "last_name": "Anderson",
    "gender": "m",
    "age": null,
    "birthday": "1971-09-11",
    "location": null,
    "email_bulk": true,
    "email_chain": true,
    "email_transactional": true,
    "web_push": true,
    "mobile_push": null,
    "sms_bulk": null,
    "sms_chain": null,
    "sms_transactional": null,
    "loyalty_id": "L02",
    "loyalty_location": null,
    "loyalty_status": null,
    "loyalty_bonuses": 0,
    "loyalty_bonuses_to_next_level": null,
    "created_date": null,
    "device": null

  }
]

Methods tries to find a collection of users by list of identifiers. Identifiers can be: email, phone, loyalty_id.

Query Parameters

Parameter Type Required Description
shop_id String true Your API key
shop_secret String true Your API secret key
by String true Type of identifier. See below.
ids Array true Array of identifiers

Supported identifiers

Identifier Description Restrictions
loyalty_id Loyalty ID No restrictions
birthday Birthday Format: YYYY-MM-DD. Processing only 5 valid dates. Other dates are skipped

Segments

The endpoint is used to put or remove user to/from static segment.

Add user to a segment

# Using all possible identifiers
curl -d "shop_id=SHOPID&shop_secret=SHOP_SECRET&email=EMAIL&phone=PHONE&segment_id=SEGMENT_ID" https://api.personaclick.com/segments/add

# With phone only
curl -d "shop_id=SHOPID&shop_secret=SHOP_SECRET&phone=PHONE&segment_id=SEGMENT_ID" https://api.personaclick.com/segments/add

# With email only
curl -d "shop_id=SHOPID&shop_secret=SHOP_SECRET&email=EMAIL&segment_id=SEGMENT_ID" https://api.personaclick.com/segments/add

// Using all possible identifiers
personaclick('segment', 'add', {
    "email": "[email protected]",
    "phone": "+10000000000",
    "segment_id": "SEGMENT_ID"
});

// With phone only
personaclick('segment', 'add', {
    "phone": "+10000000000",
    "segment_id": "SEGMENT_ID"
});

// With email only
personaclick('segment', 'add', {
    "email": "[email protected]",
    "segment_id": "SEGMENT_ID"
});

// Without any contacts: `did` is used automatically
personaclick('segment', 'add', {
    "segment_id": "SEGMENT_ID"
});
// By `did` only
sdk.addToSegment(segmentId: "333")

// With a email (`did` will be switched to the owner of the email)
sdk.addToSegment(segmentId: "333", email: "[email protected]")

// With a phone number (`did` will be switched to the owner of the phone number)
sdk.addToSegment(segmentId: "333", phone: "+10000000000")

// With both (`did` will be switched to the owner of primary contact)
sdk.addToSegment(segmentId: "333", email: "[email protected]", phone: "+10000000000")

// By `did` only
Personaсlick.addToSegment("333", null, null);

// With a email (`did` will be switched to the owner of the email)
Personaсlick.addToSegment("333", "[email protected]", null);

// With a phone number (`did` will be switched to the owner of the phone number)
Personaсlick.addToSegment("333", null, "+10000000000");

// With both (`did` will be switched to the owner of primary contact)
Personaсlick.addToSegment("333", "[email protected]", "+10000000000");
// Using all possible identifiers
sdk.segments('add', {
  "email": "[email protected]",
  "phone": "+10000000000",
  "segment_id": "SEGMENT_ID"
});

// With phone only
sdk.segments('add', {
  "phone": "+10000000000",
  "segment_id": "SEGMENT_ID"
});

// With email only
sdk.segments('add', {
  "email": "[email protected]",
  "segment_id": "SEGMENT_ID"
});

// Without any contacts: `did` is used automatically
sdk.segments('add', {
  "segment_id": "SEGMENT_ID"
});

This method adds user to a specific static segment.

POST https://api.personaclick.com/segments/add

Query Parameters

Parameter Type Required Description
shop_id String true Your API key
shop_secret String true Your API secret key
did* String User's device ID. Only for JS/iOS/Android SDK
email* String User's email
phone* String User's phone number
segment_id String Segment ID

Remove user from a segment

# Using all possible identifiers
curl -d "shop_id=SHOPID&shop_secret=SHOP_SECRET&email=EMAIL&phone=PHONE&segment_id=SEGMENT_ID" https://api.personaclick.com/segments/remove

# With phone only
curl -d "shop_id=SHOPID&shop_secret=SHOP_SECRET&phone=PHONE&segment_id=SEGMENT_ID" https://api.personaclick.com/segments/remove

# With email only
curl -d "shop_id=SHOPID&shop_secret=SHOP_SECRET&email=EMAIL&segment_id=SEGMENT_ID" https://api.personaclick.com/segments/remove

// Using all possible identifiers
personaclick('segment', 'remove', {
    "email": "[email protected]",
    "phone": "+10000000000",
    "segment_id": "SEGMENT_ID"
});

// With phone only
personaclick('segment', 'remove', {
    "phone": "+10000000000",
    "segment_id": "SEGMENT_ID"
});

// With email only
personaclick('segment', 'remove', {
    "email": "[email protected]",
    "segment_id": "SEGMENT_ID"
});

// Without any contacts: `did` is used automatically
personaclick('segment', 'remove', {
    "segment_id": "SEGMENT_ID"
});
// By `did` only
sdk.removeFromSegment(segmentId: "333")

// With a email (`did` will be switched to the owner of the email)
sdk.removeFromSegment(segmentId: "333", email: "[email protected]")

// With a phone number (`did` will be switched to the owner of the phone number)
sdk.removeFromSegment(segmentId: "333", phone: "+10000000000")

// With both (`did` will be switched to the owner of primary contact)
sdk.removeFromSegment(segmentId: "333", email: "[email protected]", phone: "+10000000000")
// By `did` only
Personaсlick.removeFromSegment("333", null, null);

// With a email (`did` will be switched to the owner of the email)
Personaсlick.removeFromSegment("333", "[email protected]", null);

// With a phone number (`did` will be switched to the owner of the phone number)
Personaсlick.removeFromSegment("333", null, "+10000000000");

// With both (`did` will be switched to the owner of primary contact)
Personaсlick.removeFromSegment("333", "[email protected]", "+10000000000");
// Using all possible identifiers
sdk.segments('remove', {
  "email": "[email protected]",
  "phone": "+10000000000",
  "segment_id": "SEGMENT_ID"
});

// With phone only
sdk.segments('remove', {
  "phone": "+10000000000",
  "segment_id": "SEGMENT_ID"
});

// With email only
sdk.segments('remove', {
  "email": "[email protected]",
  "segment_id": "SEGMENT_ID"
});

// Without any contacts: `did` is used automatically
sdk.segments('remove', {
  "segment_id": "SEGMENT_ID"
});

This method removes user from a specific static segment.

POST https://api.personaclick.com/segments/remove

Query Parameters

Parameter Type Required Description
shop_id String true Your API key
shop_secret String true Your API secret key
did* String User's device ID. Only for JS/iOS/Android SDK
email* String User's email
phone* String User's phone number
segment_id String Segment ID

Get user segments

# Using all possible identifiers
curl "shop_id=SHOPID&shop_secret=SHOP_SECRET&email=EMAIL&phone=PHONE" https://api.personaclick.com/segments/get

# With phone only
curl "shop_id=SHOPID&shop_secret=SHOP_SECRET&phone=PHONE" https://api.personaclick.com/segments/get

# With email only
curl "shop_id=SHOPID&shop_secret=SHOP_SECRET&email=EMAIL" https://api.personaclick.com/segments/get

// Using all possible identifiers
personaclick('segment', 'get', function(segments) {
    // segments (type: array of objects)
    // each object has the following properties:
    // "id" as Segment ID
    // "type" as Segment Type ("dynamic", "static")
});
sdk->getCurrentSegment()
Personaсlick.getCurrentSegment(new Api.OnApiCallbackListener() {
  @Override
  public void onSuccess(JSONArray segments) {
    // segments (type: array of objects)
  }
});
// Using all possible identifiers
sdk.segments('get').then(res => {
  // segments (type: array of objects)
  // each object has the following properties:
  // "id" as Segment ID
  // "type" as Segment Type ("dynamic", "static")
});

Response structure

[
  {
    "id": 313,
    "type": "static"
  },
  {
    "id": 314,
    "type": "dynamic"
  }
]

The method returns an array of segments of the current user.

GET https://api.personaclick.com/segments/get

Query Parameters

Parameter Type Required Description
shop_id String true Your API key
shop_secret String true Your API secret key
did* String User's device ID. Only for JS/iOS/Android SDK
email* String User's email
phone* String User's phone number

Check if a user is in a segment

# Using all possible identifiers
curl "shop_id=SHOPID&shop_secret=SHOP_SECRET&email=EMAIL&phone=PHONE" https://api.personaclick.com/segments/includes

# With phone only
curl "shop_id=SHOPID&shop_secret=SHOP_SECRET&phone=PHONE" https://api.personaclick.com/segments/includes

# With email only
curl "shop_id=SHOPID&shop_secret=SHOP_SECRET&email=EMAIL" https://api.personaclick.com/segments/includes
// Not implemented
// Not implemented
// Not implemented

Response structure

true

The method returns TRUE|FALSE if a user identified by any identifier is included in a segment.

GET https://api.personaclick.com/segments/includes

Query Parameters

Parameter Type Required Description
shop_id String true Your API key
shop_secret String true Your API secret key
email String true* User's email
phone String true* User's phone number
segment_id Integer true Segment ID

Orders

This section describes how to import orders, change its' statuses, structure and other.

Import orders

curl -i -X POST -H "Content-Type: application/json" --data-binary "@data.json" https://api.personaclick.com/sync/orders

# data.json
{
  "shop_id": "DvLWN2ZTMZ",
  "shop_secret": "EIxTuot8sj",
  "orders": [
    {
      "id": "yKsvZbWpCL",
      "status": "Delivered",
      "channel": "website",
      "date": 1602338740,
      "offline": false,
      "email": "[email protected]",
      "phone": "+15554443322",
      "loyalty_id": "000-33-444-111",
      "location_id": "7701123",
      "promocode": "vxawxSi9Uy",
      "delivery_type": "courier",
      "delivery_address": "Rouse st, 13",
      "delivery_date": "2021-12-21",
      "delivery_time": "15:00",
      "tax_free": true,
      "bank_issuer": "Sberbank",
      "bank_pos_processor": "apex",
      "bank_loyalty_program": "miles&smiles",
      "bank_total_installment": 4,
      "payment_card_provider": "mastercard"
      "gift_package":true,
      "value": {
        "total": 200.13,
      },
      "payment_structure": {
        "cash": 190,
        "bonuses": 15,
        "delivery": 20,
        "discount": 24.87
      },
      "items": [
        {
          "id": "ITEM-ID-1",
          "price": 205,
          "quantity": 1,
          "status": "cancelled",
          "original_price": 230,
          "discount_product": 30,
          "discount_coupon": 10,
          "discount_bonuses": 20,
          "delivery_company": "ups",
          "barcode_id": "195204003541",
          "line_id": "195204003541-22323443-123434",
          "cancel_reason": "over size",
        },
}
        ...
      ]
    },
    ...
  ]
}

If a request contains orders with IDs which are already saved in our database, statuses and structure of this orders will be updated.

Query Parameters

Parameter Type Required Description
shop_id String true Your API key
shop_secret String true Your API secret key
orders Array true List of orders. See description below.

Description of orders objects:

Parameter Type Required Description
id String true Order ID
status String true Order's status
channel String true Channel where order was updated
date Integer true Date and time when order status changed
offline Boolean false Flags orders as offline. Default false.
email String false User's email
phone String false User's phone
loyalty_id String false User's loyalty ID
location_id String false User's location (city) ID
promocode String false Promo code used in the order
delivery_type String false Delivery type
delivery_address String false Destination address for CRM
delivery_date Date false Planned delivery date. Format: "YYYY-MM-DD"
delivery_time Time false Planned delivery time. Format: "HH:MM"
payment_type String false Payment type. Can by any string value. Ex: cash, card, wire.
tax_free Boolean false Tax free
bank_issuer String false Bank issuer
bank_pos_processor String false Bank POS processor
bank_loyalty_program String false Bank loyalty program
bank_total_installment Integer false Bank total installment
payment_card_provider String false Payment card provider
gift_package Boolean false Gift packaged
value Object true Describes order's value parts. See below.
payment_structure Object false Describes order's payment_structure parts. See below.
items* Array true Describes order's products. See below.

Description of value object:

Parameter Type Required Description
total Numeric true Order's total value

Description of payment_structure object:

Parameter Type Required Description
cash Numeric false Describes how much of order's value was paid by real money.
bonuses Numeric false Describes how much of order's value was paid by bonuses.
delivery Numeric false Describes price of order's delivery
discount Numeric false Describes discount value of the order.

Description of items objects:

Parameter Type Required Description
id String true ID of purchased product
price Numeric true Price of 1 unit of purchased product
quantity Integer true Quantity of mentioned products in the order
status String false Item status, Can by only: created, invoiced, shipped, delivered, cancelled, refunded
original_price Numeric false Original item price
discount_product Numeric false Discount item
discount_coupon Numeric false Discount item coupon
discount_bonuses Numeric false Discount item bonuses
delivery_company String false Delivery item company
barcode String false Item barcode
line_id String false Unique identifier of the item position in the order on the store's side
cancel_reason String false Cancel reason

Send cancelled orders

You can change order's status to "Cancelled". Order status must linked with our system status. Just send new request with the same order ID and order will be updated.

curl -i -X POST -H "Content-Type: application/json" --data-binary "@data.json" https://api.personaclick.com/sync/orders

# data.json
{
  "shop_id": "DvLWN2ZTMZ",
  "shop_secret": "EIxTuot8sj",
  "orders": [
    {
      "id": "yKsvZbWpCL",
      "status": "Cancelled"
    },
    ...
  ]
}

Query Parameters

Parameter Type Required Description
shop_id String true Your API key
shop_secret String true Your API secret key
orders Array true List of orders. See description below.

Description of orders objects:

Parameter Type Required Description
id String true Order ID
status String true Order's status

Get users last order products

curl https://api.personaclick.com/orders/last_for_user?shop_id=SHOP_ID&did=DID&sid=SEANCE_ID

If a request fetches user's last purchase and returns list of purchased products. If there was not purchases, empty array is returned.

Query Parameters

Parameter Type Required Description
shop_id String true Your API key
did String true Users device ID
sid String true Users session ID

Get user's orders

curl https://api.personaclick.com/orders/by_user?shop_id=SHOP_ID&shop_secret=SHOP_SECRET&did=DID&date_from=YYYY-MM-DD
// Not supported
// Not supported
// Not supported
// Not supported

Returns a list of user's orders (ascending by date and internal ID). User is identified by did, email, phone, loyalty_id or external_id.

Query Parameters

Parameter Type Required Description
shop_id String true Your API key
shop_secret String true Your API secret key
did String false User's device ID
email String false User's email
phone String false User's phone
loyalty_id String false User's loyalty ID
external_id String false User's external ID
date_from Date false Date in YYYY-MM-DD format

Promo codes

Service provides endpoints for promo codes management.

List of promo codes lists

curl https://api.personaclick.com/promo_codes?shop_id=SHOPID&shop_secret=SHOP_SECRET

The above command returns JSON structured like this:

[
  {
    "id": 3184,
    "name": "Abandoned cart trigger discount codes",
    "available": 3744
  }
]

This method returns list of existing promo codes lists with count of available promo codes in each list.

HTTP Request

GET https://api.personaclick.com/promo_codes

Query Parameters

Parameter Required Type Description
shop_id true string Your API key
shop_secret true string Your API secret key
active false integer Return only lists with at least 1 free code (value 1)
exclude false string Comma separated list of IDs of lists to exclude
include false string Comma separated list of IDs of lists to include in result (excludes others)
offset false integer Offset for pagination. Default: 0
limit false integer Limit for pagination. Default: 1000

Errors

When promo secret key is wrong, method returns 403 error.

Upload promo codes

Headers

Content-type: application/json

Body example

{
    "shop_id": "...",
    "shop_secret": "...",
    "id": "...",
    "codes": [ "code1", "code2", "code3" ]
}

Request example

curl --header "Content-Type: application/json" \
  --request POST \
  --data-binary "@data.json" \
  https://api.personaclick.com/promo_codes

Method uploads list of unique promo codes to the selected list. All non-unique promo codes will be excluded.

HTTP Request

POST https://api.personaclick.com/promo_codes

Content-Type: application/json

Query Parameters

Parameter Required Description
shop_id true Your API key
shop_secret true Your API secret key
id true Promo codes list ID
codes true List of promo codes

Errors

When promo codes list is empty, method returns 404 error.

Fetch promo code

curl https://api.personaclick.com/promo_codes/fetch?did=DEVICE_ID&shop_id=SHOPID&id=PROMOCODE_LIST_ID
personaclick("get_promo_code", {id: PROMOCODE_LIST_ID}, success_callback, error_callback);

The above command returns JSON structured like this:

{"code":  "UNIQUE_CODE"}

Method provides service for unique promo codes fetching.

Note: unique promo codes are limited. Store fetched promo code during user's session.

HTTP Request

GET https://api.personaclick.com/promo_codes/fetch

Query Parameters

Parameter Required Description
did true Device ID. You get it from init method in SDK.
shop_id true Your API key
id true Promo codes list ID
sid false Temporary user session ID

Errors

When promo codes list is empty, method returns 404 error.

Bonuses

Service provides endpoints for bonuses management.

Import bonuses status

Headers

Method: POST
Content-type: application/json

Body example

{
  "shop_id":"...",
  "shop_secret":"...",
  "bonuses": [
    {
      "email": "...",
      "phone": "...",
      "loyalty_id": "...",
      "current_status": "...",
      "total_balance": ...,
      "total_used": ...,
      "total_burned": ...,
      "total_cancelled": ...,
      "total_inactive": ...,
      "total_rewarded": ...,
      "event": "...",
      "order_id": "...",
      "bonus_status": "...",
      "amount_changed": "...",
      "activated_at": "...",
      "expiration": "...",
      "activity": "...",
      "balance": ...
    }, ...
  ]
}

Request example

curl --header "Content-Type: application/json" \
  --request POST \
  --data-binary "@data.json" \
  https://api.personaclick.com/import/bonuses

Method uploads current bonuses status.

HTTP Request

POST https://api.personaclick.com/import/bonuses

Content-Type: application/json

Query Parameters

Parameter Required Description
shop_id true Your API key
shop_secret true Your API secret key
email* true Promo codes list ID
phone* true List of promo codes
loyalty_id* true List of promo codes

Properties

Parameter Type Description
current_status String Current status
total_balance Float Total balance
total_used Float Total used
total_burned Float Total burned out
total_cancelled Float Total cancelled
total_inactive Float Total inactive
total_rewarded Float Total rewarded
purchase_date Date Date in format YYYY-MM-DD HH:MM:SS
event String Status change event
order_id String Order ID
bonus_status String Status of bonuses
amount_changed String Amount of bonus changes
activated_at Date Date in format YYYY-MM-DD HH:MM:SS
expiration Date Date in format YYYY-MM-DD HH:MM:SS
activity String The action that changed the balance
balance Float Current bonuses balance

Errors

Loyalty program

Service provides endpoints for loyalty program management.

Get balance

Request example

curl 'https://api.personaclick.com/loyalty/basic/balance?shop_id=SHOP_ID&shop_secret=SHOP_SECRET&phone=PHONE&order_total=ORDER_TOTAL'

The above command returns JSON structured like this:

{
    "confirmed": 123,
    "pending": 456,
    "expiring": 789,
    "expire_in": "2022-12-12 23:59:59 UTC",
    "available_in_order": 100, // How many bonuses can be spent in this purchase
    "payable_amount": 50 // How much it will in currency if exchange rate is not 1:1
}

Method return current bonuses balance.

HTTP Request

GET https://api.personaclick.com/loyalty/basic/balance

Query Parameters

Parameter Required Description
shop_id true Your API key
shop_secret true Your API secret key
email* true User's email
phone* true User's phone number
expire_in optional Bonuses expiration date (DD-MM-YYYY)
order_total optional Order total

API response

Name Type Description
confirmed Int Available bonuses
pending Int Pending bonuses
expiring Int Bonuses that will be expired
expire_in Datetime Expiring period
available_in_order Int Available bonuses for use in the order

Get SMS code

Request example

curl 'https://api.personaclick.com/loyalty/basic/init_bonus_usage?shop_id=SHOP_ID&shop_secret=SHOP_SECRET&phone=PHONE&bonus_points=BONUS_POINTS'

The above command returns JSON structured like this:

{
    "status": "success",
    "sms_code": 123456
}

Method return SMS code.

HTTP Request

GET https://api.personaclick.com/loyalty/basic/init_bonus_usage

Query Parameters

Parameter Required Description
shop_id true Your API key
shop_secret true Your API secret key
email* true User's email
phone* true User's phone number
bonus_points true Bonuses, which client wants to validate

API response

Name Type Description
sms_code Int SMS code

Validate SMS code

Request example

curl --location --request POST 'https://api.personaclick.com/loyalty/basic/use_bonus_points?phone=PHONE&shop_id=SHOP_ID&shop_secret=SHOP_SECRET&bonus_points=BONUS_POINTS&confirm_code=true&sms_code=SMS_CODE'

The above command returns JSON structured like this:

{
    "confirmation": "success",
    "confirmed": 123456
}

Method validate SMS code.

HTTP Request

POST https://api.personaclick.com/loyalty/basic/use_bonus_points

Query Parameters

Parameter Required Description
shop_id true Your API key
shop_secret true Your API secret key
email* true User's email
phone* true User's phone number
bonus_points true Bonuses, which client wants to validate
confirm_code true Param for validate
sms_code true SMS code

API response

Name Type Description
confirmation String Response message
confirmed int Validated bonuses

Decrease bonuses

Request example

curl --location --request POST 'https://api.personaclick.com/loyalty/basic/use_bonus_points_confirmed?phone=PHONE&shop_id=SHOP_ID&shop_secret=SHOP_SECRET&bonus_points=BONUS_POINTS&sms_code=SMS_CODE'

The above command returns JSON structured like this:

{
    "confirmation": "success",
    "confirmed": 123456
}

Method decrease bonuses.

HTTP Request

POST https://api.personaclick.com/loyalty/basic/use_bonus_points_confirmed

Query Parameters

Parameter Required Description
shop_id true Your API key
shop_secret true Your API secret key
email* true User's email
phone* true User's phone number
bonus_points true Bonuses, which client wants to validate
sms_code true SMS code

API response

Name Type Description
status String Response status
confirmed int Validated bonuses

Decrease bonuses without SMS code

Request example

curl --location --request POST 'https://api.personaclick.com/loyalty/basic/use_bonus_points?phone=PHONE&shop_id=SHOP_ID&shop_secret=SHOP_SECRET&bonus_points=BONUS_POINTS'

The above command returns JSON structured like this:

{
    "confirmation": "success",
    "confirmed": 123456
}

Method decrease bonuses without SMS code.

HTTP Request

POST https://api.personaclick.com/loyalty/basic/use_bonus_points

Query Parameters

Parameter Required Description
shop_id true Your API key
shop_secret true Your API secret key
email* true User's email
phone* true User's phone number
bonus_points true Bonuses, which client wants to validate

API response

Name Type Description
status String Response status
confirmed int Validated bonuses

Increase bonuses

Request example

curl --location --request POST 'https://api.personaclick.com/loyalty/basic/event_bonus?phone=PHONE&shop_id=SHOP_ID&shop_secret=SHOP_SECRET&event=EVENT&amount=AMOUNT'

The above command returns JSON structured like this:

{
    "status": "success"
}

Method increase bonuses. This method is used to increase user bonuses that aren't related to an order. It can be any action, for example, registration on the site. Bonuses added by this method have activated status and can be used immediately

HTTP Request

POST https://api.personaclick.com/loyalty/basic/event_bonus

Query Parameters

Parameter Required Description
shop_id true Your API key
shop_secret true Your API secret key
email* true User's email
phone* true User's phone number
event true A unique event code that's used once for a user to award bonuses for an action. For example, "registration".
amount true Bonuses amount

API response

Name Type Description
status String Response status

Net Promoter Score

Endpoints is used to work with NPS service.

Glossary:

NPS categories

This endpoints returns a list of active categories. Categories list can be customized on NPS settings page in backoffice.

Note: if you provide any of user identifiers (see query params table), questions and "thank you" messages can be personalized.

curl https://api.personaclick.com/nps/categories?shop_id=SHOPID
personaclick('nps', 'categories', success, failure);
// Not described yet
// Not described yet

The above command returns JSON structured like this:

[
  {
    "id": 1,
    "code": "website",
    "name": "Online checkout quality",
    "promoter_question": "Which features do you value/use the most?",
    "passive_question": "How can we improve your experience?",
    "detractor_question": "What was missing or disappointing in your experience with us?",
    "promoter_success": "Thanks for your feedback, Mr. John Smith. It’s great to hear that you’re a fan of our product. Your feedback helps us discover new opportunities to improve and make sure you have the best possible experience.",
    "passive_success": "Thanks for your feedback. Our goal is to create the best possible product, and your thoughts, ideas, and suggestions play a major role in helping us identify opportunities to improve.",
    "detractor_success": "Thanks for your feedback. We highly value all ideas and suggestions from our customers, whether they’re positive or critical. In the future, our team might reach out to you to learn more about how we can further improve our services so that it exceeds your expectations."
  },
  {
    "id": 3,
    "code": "delivery",
    "name": "Delivery quality survey",
    "promoter_question": "Which features do you value/use the most?",
    "passive_question": "How can we improve your experience?",
    "detractor_question": "What was missing or disappointing in your experience with us?",
    "promoter_success": "Thanks for your feedback, Mr. John Smith. It’s great to hear that you’re a fan of our product. Your feedback helps us discover new opportunities to improve and make sure you have the best possible experience.",
    "passive_success": "Thanks for your feedback. Our goal is to create the best possible product, and your thoughts, ideas, and suggestions play a major role in helping us identify opportunities to improve.",
    "detractor_success": "Thanks for your feedback. We highly value all ideas and suggestions from our customers, whether they’re positive or critical. In the future, our team might reach out to you to learn more about how we can further improve our services so that it exceeds your expectations."
  }
]

HTTP Request

GET https://api.personaclick.com/nps/categories

Query Parameters

Parameter Type Required Description
shop_id String true Your API key. JS SDK handles it automatically.

NPS channels

Get list of available channels, from which NPS review can be created. Channels list can be customized on NPS settings page in backoffice.

curl https://api.personaclick.com/nps/channels?shop_id=SHOPID
personaclick('nps', 'channels', success, failure);
// Not described yet
// Not described yet

The above command returns JSON structured like this:

[
  {
    "id": 1,
    "code": "website",
    "name": "Online checkout quality"
  },
  {
    "id": 2,
    "code": "ios_app",
    "name": "iOS mobile app"
  },
  {
    "id": 3,
    "code": "ios_app",
    "name": "iOS mobile app"
  },
  {
    "id": 4,
    "code": "pos",
    "name": "POS terminal"
  }
]

HTTP Request

GET https://api.personaclick.com/nps/channels

Query Parameters

Parameter Type Required Description
shop_id String true Your API key. JS SDK handles it automatically.

NPS reviews

Get list of published NPS reviews. Limited to 1000 reviews per request.

curl https://api.personaclick.com/nps/reviews?shop_id=SHOPID&shop_secret=SECRET
// Not needed. See cURL.
// Not needed. See cURL.
// Not needed. See cURL.

The above command returns JSON structured like this:

[
  {
    "id": 1,
    "channel": "email",
    "category": "delivery",
    "rate": 7,
    "comment": "Lorem ipsum",
    "client_id": 1515915625535836508,
    "email": "[email protected]",
        "phone": "79876543210",
        "created_at": "2023-07-21T02:35:06.374Z"
  },
  {
    "id": 2,
    "channel": "popup",
    "category": "checkout",
    "rate": 9,
    "comment": null,
    "client_id": 1515915625535836508,
    "email": "[email protected]",
        "phone": "79876543210",
        "created_at": "2023-07-21T02:35:06.374Z"
  }
]

HTTP Request

GET https://api.personaclick.com/nps/reviews

Query Parameters

Parameter Type Required Description
shop_id String true Your API key.
shop_secret String true Your API secret key.
date_from String false Filter by date: start date.
date_to String false Filter by date: end date.
channel String false Channel code.
category String false Category code.

Save review

// Not allowed
// Full form
personaclick("nps", "review", {
    channel: "channel_code",
    category: "category_code",
    rate: 7,
    comment: "Some comment"
}, success, failure);

// Without comment
personaclick("nps", "review", {
    channel: "channel_code",
    category: "category_code",
    rate: 10
}, success, failure);
// Basic usage
sdk.review(rate: 3, channel: "ios_app", category: "checkout") { _ in
  print("Review is posted")
}

// Rate order
sdk.review(rate: 6, channel: "ios_app", category: "checkout", order_id: "ORDER-3341") { _ in
  print("Review is posted")
}

// With comment
sdk.review(rate: 9, channel: "ios_app", category: "checkout", comment: "Nice application, thank you!") { _ in
  print("Review is posted")
}

// With comment and order_id
sdk.review(rate: 10, channel: "ios_app", category: "checkout", order_id: "ORDER-3341", comment: "Nice application, thank you!") { _ in
  print("Review is posted")
}
// Not described yet

Create an NPS review for the specific survey and user. To identify user you can use one of the listed identifiers:

If there is existing review from the same user, channel, category and date, it will be updated instead of creating new one.

HTTP Request

POST https://api.personaclick.com/nps/create

Query Parameters

Response on success:

    {
        "status": "success"
    }

Response on failure:

    {
        "status": "error",
        "payload": {
          "message": "error message"
        }
    }

One of the listed user identifiers is required: did, email, phone, order_id.

Parameter Type Required Description
shop_id String true Your API key
shop_secret String true Your secret API key
did String false Device ID of the user. SDK handles it automatically.
sid true Temporary user session ID. Required when sending NPS with did identifier.
email String false User's email
phone String false User's phone
loyalty_id String false User's loyalty ID
order_id String false Order ID, related to the current survey
channel String true NPS channel code
category String true NPS process category code
rate Integer true Score of the rated process: 1..10
comment String false Optional answer to the follow-up question

SMS messaging

Section describes how to send SMS messages

Transactional SMS

curl -i -X POST -H "Content-Type: application/json" --data-binary "@data.json" https://api.personaclick.com/sms/transactional

# data.json
{
  "shop_id": "DvLWN2ZTMZ",
  "shop_secret": "EIxTuot8sj",
  "code": "...",
  "phone": "...",
  "variables": {
    "url": "https://mydomain.com/page/1",
    "variable_1": "value_1",
    "variable_2": "value_2",
    ...
  }
}
// REST API only. See cURL.
// REST API only. See cURL.
// REST API only. See cURL.

Requirements

Endpoint: GET https://api.personaclick.com/sms/transactional

Content type: application/json

Data format: JSON body.

Query Parameters

Parameter Type Required Description
shop_id String true Your API key
shop_secret String true Your API secret key
code String true Campaign unique identifier
phone String true User's phone number
variables Object true Object of key-pair variables for template parser. See example.

Multi-messaging

Method of multi-channel notifications, when the platform automatically chooses the cheapest and more efficient way to deliver transactional message to a recipient.

Supported channels:

Initial tasks

Before sending campaign you have to setup it:

  1. Prepare transactional email template
  2. Prepare transactional web/mobile push template
  3. Prepare transactional SMS template
  4. Create multi-channel campaign and select created templates for every channel you want to use in the campaign.
  5. Done.

In templates you can use variables and operators to customize final content. Template engine - Liquid.

Sending message

curl -i -X POST -H "Content-Type: application/json" --data-binary "@data.json" https://api.personaclick.com/transact

# data.json
{
  "shop_id": "DvLWN2ZTMZ",
  "shop_secret": "EIxTuot8sj",
  "email": "...",
  "phone": "...",
  "code": "...",
  "variables": {
    "first_name": "John",
    "last_name": "Connor",
    "promocode": "IDDQD",
    "variable_1": "value_1",
    "variable_2": "value_2",
    ...
  }
}
// REST API only. See cURL.
// REST API only. See cURL.
// REST API only. See cURL.

When sending a message, you must to send:

Requirements

Endpoint: GET https://api.personaclick.com/transact

Content type: application/json

Data format: JSON body.

Query Parameters

Parameter Type Required Description
shop_id String true Your API key
shop_secret String true Your API secret key
email* String true User's email
phone* String true User's phone number
code String true Multi-channel campaign unique code
send_everywhere Boolean false Send to all channels, except SMS. Default false
variables Object true Object of key-pair variables for template parser. See example
  • One of identifiers must present in request: email or phone. It's used to identify user.

URL shortener

This service provides functionality to make shortened URLs and generate QR codes for an URL.

Create short URL

Headers

Content-type: application/json

Body example

{
    "shop_id": "...",
    "shop_secret": "...",
    "links": [
        {
            "url": "https://example.com/page/1/?utm_source=source...",
        },
        {
            "url": "https://example.com/page/2/?utm_source=source...",
            "lifetime": 60
        },
        {
            "url": "https://example.com/page/3/?utm_source=source...",
            "code": "a",
            "lifetime": 10
        }
    ]
}

Request example

curl --header "Content-Type: application/json" \
  --request POST \
  --data '{"shop_id":"...","shop_secret":"...","links":[{"url":"https://example.com/page/1"},{"url":"https://example.com/page/1","code":"a"}]}' \
  https://api.personaclick.com/url/create

Response example:

[
  {
    "source": "https://example.com/page/1",
    "url": "https://personaclick.dev/x27FyAlR"
  },
  {
    "source": "https://example.com/page/2",
    "url": "https://personaclick.dev/a"
  }
]

The endpoint allows to create 1 to N shortened URLs. Use batch request to shorten hundreds of URLs at once.

HTTP Request

Method Endpoint Content-type
POST https://api.personaclick.com/url/create application/json

Query Parameters

This is JSON request. All data must be send as JSON body. Do not forget to set Content-type: application/json.

Parameter Type Required Description
shop_id String true Your API key
shop_secret String true Your secret API key
links Array true List of URLs to shorten. At least 1 element must present.
url String true Source URL to shorted. Must be present in each element if list array.
lifetime Integer false Number of days shortened link to be alive. Link will be deleted after this number of days. Min value: 1. Max value: 90. Default value: 30. Try not to use large numbers, because number of unique shortened URLs is limited.
code String false Use code property to manually create links with specified URL. Keep in mind: every time you set code manually, it overrides previous link with the same code.
domain String false Custom domain name for URL shortener. Must be whitelisted with support team before usage.

Products and catalog

Service is used to manage products and categories.

Request product list

# Basic
curl https://api.personaclick.com/products?shop_id=...&did=...&sid=...

# Filter by brands
curl https://api.personaclick.com/products?shop_id=...&did=...&sid=...&brands=BRAND_1,BRAND_2

# Filter by categories
curl https://api.personaclick.com/products?shop_id=...&did=...&sid=...&categories=CATEGORY_1,CATEGORY_2

# Filter by locations
curl https://api.personaclick.com/products?shop_id=...&did=...&sid=...&locations=LOCATION_1,LOCATION_2

# Filter by merchants
curl https://api.personaclick.com/products?shop_id=...&did=...&sid=...&merchants=MERCHANT_1,MERCHANT_2

# Filter by params
curl https://api.personaclick.com/products?shop_id=...&did=...&sid=...&filters={"PARAM_NAME_1": ["PARAM_VALUE_1", "PARAM_VALUE_2"], "PARAM_NAME_2": ["PARAM_VALUE_1", "PARAM_VALUE_2"]}

# Filter by true|false params. Send boolean params as string
curl https://api.personaclick.com/products?shop_id=...&did=...&sid=...&filters={"PARAM_NAME_1": ["true"], "PARAM_NAME_2": ["false"]}

// No implementation. See CURL
sdk.getProductsList(
  brands: String?,
  merchants: String?,
  categories: String?,
  locations: String?,
  limit: Int?,
  page: Int?,
  filters: [String : Any]?
) {
  Result<ProductsListResponse,
  SDKError> in //productsListResponse in // Result response
}
// No implementation. See CURL

HTTP Request

GET https://api.personaclick.com/products

Query Parameters

Parameter Required Description
did true Device ID. You get it from init method in SDK.
shop_id true Your API key
sid true Temporary user session ID
limit false Limit of results
page false Page of results
locations false Comma separated list of locations IDs
brands false Comma separated list of brands to filter
merchants false Comma separated list of merchants to filter
categories false Comma separated list of categories to filter
filters false Optional escaped JSON string with filter parameters. For example: {"bluetooth":["yes"],"offers":["15% cashback"],"weight":["1.6"]}
filters_search_by false Available options for filter: name, quantity, popularity

API response

Name Type Description
brands array Array with information about brands. Each object has the following properties:
* name – brand name (string)
* picture – brand picture (string)
filters array Array with information about filters. Each object has the following properties:
* filter – fitler object. Has the following properties:
* count – total count of products whith this parameters (number)
* values – array of values (object). Has the following properties:
* value – value label. (string)
* count – cont of products whith this parameter (number)
price_range object Min and max price of products. Has the following properties:
* min – min price (number)
* max – max price (number)
products array Array with information about products. Each object has the following properties:
* brand – product brand (string)
* currency – product currency (string, corresponds to the currency of the personal account in PersonaClick, or a custom value specified in the shop settings in the personal account)
* id – product ID (string)
* is_new – product property (boolean, default - null)
* name – product name (string)
* old_price – product old price (string, default - 0)
* picture – product's picture URL in the PersonaClick storage (string)
* price – product price (number)
* price_formatted – product price with currency (string)
* url – product URL (string)
Additional properties. If a parameter "extended" is passed in the request
* barcode – product barcode (string)
* categories – product categories (array). Has the following properties:
* id – category id (string)
* name – category name (string)
* parent – parent category id (string)
* params – array with information about params. Each object has the following properties:
* key – param name (string)
* values – array of values (array)
products_total number Total count of products

Get product info

curl https://api.personaclick.com/products/get?shop_id=...&item_id=...
// No implementation. See CURL
// No implementation. See CURL
// No implementation. See CURL

REST method returns this JSON structure

{
  "name": "...",
  "description": "...",
  "price": "...",
  "currency": "...",
  "url": "...",
  "picture": "..."
}

Returns basic product info.

GET https://api.personaclick.com/products/get

Query Parameters

Parameter Type Required Description
shop_id String true Your API key
item String true Product ID

Get product stats

curl https://api.personaclick.com/products/counters?shop_id=...&item=...
personaclick('products', 'counters', ITEM, success, error)
// No implementation. See CURL
// No implementation. See CURL

REST method returns this JSON structure

{
  "daily": {
    "view": 123,
    "cart": 456,
    "purchase": 789
  },
  "now": {
    "view": 123,
    "cart": 456,
    "purchase": 789
  }
}

Returns basic product info.

GET https://api.personaclick.com/products/counters

Query Parameters

Parameter Type Required Description
shop_id String true Your API key
item_id String true Product ID

Get subscriptions for products in stock

curl https://api.personaclick.com/products/subscribers/stock?shop_id=...&shop_secret=...
// No implementation. See CURL
// No implementation. See CURL
// No implementation. See CURL

REST method returns this JSON structure

[
  {
    "id": "ID1",
    "barcode": "BC101",
    "quantity": 337,
    "date": "2020-01-12",
    "contacts": [
      "[email protected]",
      "[email protected]"
    ]
  },
  {
    "id": "ID2",
    "barcode": "BC102",
    "quantity": 13,
    "date": "2020-08-11",
    "contacts": [
      "[email protected]",
      "[email protected]"
    ]
  }
]

Returns list of products and a number of subscribers for each product in stock.

GET https://api.personaclick.com/products/subscribers/stock

Query Parameters

Parameter Type Required Description
shop_id String true Your API key
shop_secret String true Shop secret key

Response details

Parameter Type Description
id String Product ID
barcode String Product barcode
subscribers Integer Number of subscribers for the product
date String Date of the last subscription

Get subscriptions for products price drop

curl https://api.personaclick.com/products/subscribers/price?shop_id=...&shop_secret=...
// No implementation. See CURL
// No implementation. See CURL
// No implementation. See CURL

REST method returns this JSON structure

[
  {
    "id": "ID1",
    "barcode": "BC101",
    "quantity": 337,
    "date": "2020-01-12",
    "contacts": [
      "[email protected]",
      "[email protected]"
    ]
  },
  {
    "id": "ID2",
    "barcode": "BC102",
    "quantity": 13,
    "date": "2020-08-11",
    "contacts": [
      "[email protected]",
      "[email protected]"
    ]
  }
]

Returns list of products and a number of subscribers for each product's price drop.

GET https://api.personaclick.com/products/subscribers/price

Query Parameters

Parameter Type Required Description
shop_id String true Your API key
shop_secret String true Shop secret key

Response details

Parameter Type Description
id String Product ID
barcode String Product barcode
subscribers Integer Number of subscribers for the product
date String Date of the last subscription

Get status of subscription for "Back in Stock" trigger

// No implementation. See JavaScript
personaclick("check_trigger", "product_price_decrease", params, success, error);
// No implementation. See JavaScript
// No implementation. See JavaScript

API method returns this boolean status

Returns boolean status of subscription.

Query Parameters

Parameter Type Required Description
params Object true Object with request parameters.
success Function true Callback-function, where the API response will be passed to. Response type: object.
error Function false Callback-function to be called when an error occurs (any HTTP status code other than 200).

Request parameters

Parameter Type Required Description
item string/number true Product ID
email string false Email for subscription checking
phone string false Phone for subscription checking
loyalty_id string false Loyalty ID for subscription checking

Get status of subscription for product price drop

// No implementation. See JavaScript
personaclick("check_trigger", "product_available", params, success, error);
// No implementation. See JavaScript
// No implementation. See JavaScript

API method returns this boolean status

Returns boolean status of subscription.

Query Parameters

Parameter Type Required Description
params Object true Object with request parameters.
success Function true Callback-function, where the API response will be passed to. Response type: object.
error Function false Callback-function to be called when an error occurs (any HTTP status code other than 200).

Request parameters

Parameter Type Required Description
item string/number true Product ID
email string false Email for subscription checking
phone string false Phone for subscription checking
loyalty_id string false Loyalty ID for subscription checking

List not widgetable products

curl https://api.personaclick.com/products/not_widgetable?shop_id=...&shop_secret=...
// No implementation. See shell
// No implementation. See shell
// No implementation. See shell

API method returns a list like this:

{
  "status": "success",
  "data": {
    "items": [
      { "uniqid": "YOUR_SKU", "name": "...", "url": "...", "image_url": "", "price": ..., "image_downloading_error": "..."},
      { "uniqid": "YOUR_SKU", "name": "...", "url": "...", "image_url": "", "price": ..., "image_downloading_error": "..."},
    ]
  }
}

Returns a list of avaiable and not ignored products which are not widgetable: can't be displayed in search, recommendations and messages due to missing one of mandatory parameters (name, price, url or image_url) or failed to fetch product's photo during import operation.

Categories

Service provides access to categories endpoint.

Request categories

curl https://api.personaclick.com/products/categories

HTTP Request

GET https://api.personaclick.com/products/categories

Query Parameters

Parameter Required Description
shop_id true Your API key
shop_secret true Your Secret key
depth false (0 - root categories, 1 - root and first level of childs, etc.)
exclude false An array of categories to exclude from the response
only_discount false Boolean. Only categories with discount products.
locations false String. Comma separated list of locations IDs

Response example

[
  {
    "id": 19,
    "external_id": "482",
    "name": "Jewelry",
    "url": "https://demo.site.com/categories/jewelry",
    "parent_id": null,
    "parent_external_id": null,
    "children":  [
      {
        "id": 31,
        "external_id": "483",
        "name": "Rings",
        "url": "https://demo.site.com/categories/rings",
        "parent_id": 19,
        "parent_external_id": "482",
        "children": []
      }
    ]
  },
  {
    "id": 4,
    "external_id": "479",
    "name": "Baby & Kids",
    "url": "https://demo.site.com/categories/baby",
    "parent_id": null,
    "parent_external_id": null,
    "children": [
      {
        "id": 9,
        "external_id": "480",
        "name": "Clothing Sets",
        "url": "https://demo.site.com/categories/baby-kids-clothing-sets",
        "parent_id": 4,
        "parent_external_id": "479",
        "children": []
      }
    ]
   }
]

Dynamic filter guide for category

Request

curl https://api.personaclick.com/category/{%category_id%}

HTTP Request

GET https://api.personaclick.com/category/{%category_id%}

Query Parameters

Parameter Required Description
did true Device ID. You get it from init method in SDK.
shop_id true Your API key
sid true Temporary user session ID
limit false Limit of results
page false Page of results
locations false Comma separated list of locations IDs
brands false Comma separated list of brands to filter
filters false Optional escaped JSON string with filter parameters. For example: {"bluetooth":["yes"],"offers":["15% cashback"],"weight":["1.6"]}

API response

Name Type Description
brands array Array with information about brands. Each object has the following properties:
* name – brand name (string)
* picture – brand picture (string)
filters array Array with information about filters. Each object has the following properties:
* filter – fitler object. Has the following properties:
* count – total count of products whith this parameters (number)
* values – array of values (object). Has the following properties:
* value – value label. (string)
* count – cont of products whith this parameter (number)
price_range object Min and max price of products. Has the following properties:
* min – min price (number)
* max – max price (number)
products array Array with information about products. Each object has the following properties:
* brand – product brand (string)
* currency – product currency (string, corresponds to the currency of the personal account in PersonaClick, or a custom value specified in the shop settings in the personal account)
* id – product ID (string)
* is_new – product property (boolean, default - null)
* name – product name (string)
* old_price – product old price (string, default - 0)
* picture – product's picture URL in the PersonaClick storage (string)
* price – product price (number)
* price_formatted – product price with currency (string)
* url – product URL (string)
Additional properties. If a parameter "extended" is passed in the request
* barcode – product barcode (string)
* categories – product categories (array). Has the following properties:
* id – category id (string)
* name – category name (string)
* parent – parent category id (string)
* params – array with information about params. Each object has the following properties:
* key – param name (string)
* values – array of values (array)
products_total number Total count of products

Notifications center

Section describes the notifications center endpoints.

Return all messages sent to a user

curl https://api.personaclick.com/notifications?shop_id=...&shop_secret=...&email=...&date_from=YYYY-MM-DD&type=trigger&channel=mobile_push
curl https://api.personaclick.com/notifications?shop_id=...&shop_secret=...&phone=...&date_from=YYYY-MM-DD&type=trigger,transactional&channel=mobile_push,sms
curl https://api.personaclick.com/notifications?shop_id=...&shop_secret=...&loyalty_id=...&date_from=YYYY-MM-DD&type=bulk,trigger,transactional&channel=mobile_push
curl https://api.personaclick.com/notifications?shop_id=...&shop_secret=...&external_id=...&date_from=YYYY-MM-DD&type=bulk,trigger,transactional&channel=mobile_push,email,web_push

Response format:

{
  "status": "success",
  "payload": {
    "messages": [
      {
        "type": "trigger",
        "campaign_id": ...,
        "code": "...",
        "date": "2023-07-06",
        "sent_at": "2023-07-06T14:25:21.000Z",
        "subject": "...",
        "body": "...",
        "url": "...",
        "icon": "...",
        "picture": "...",
        "statistics": {
          "opened": true,
          "clicked": false,
          "hard_bounced": false,
          "soft_bounced": false,
          "complained": false,
          "unsubscribed": false,
          "purchased": false
        }
      }, ...
    ]
  }
}
// REST API only. See cURL.
sdk.getAllNotifications(
  type: String,
  phone: String?,
  email: String?,
  userExternalId: String?,
  userLoyaltyId: String?,
  channel: String?,
  limit: Int?,
  page: Int?,
  dateFrom: String?
) {
  Result<UserPayloadResponse, SDKError> in // Result response
}
// REST API only. See cURL.

Requirements

Endpoint: GET https://api.personaclick.com/notifications

Query Parameters

Parameter Type Required Description
shop_id String true Your API key
shop_secret String true Your API secret key
phone* String true User's phone number
email* String true User's email
loyalty_id* String true User's loyalty ID
external_id* String true User's external ID
date_from String true Date in YYYY-MM-DD format. Selects all messages from this date to the current day. Choose date not older than 2 weeks ago, otherwise it will slowdown everything drammatically.
type String true Comma-separated list of message types: bulk, trigger, transactional. Choose wisely: every type slows down performance of the method. Use only required types of messages.
channel String true Comma-separated list of message channels: email, sms, web_push, mobile_push, telegram. Choose wisely: every channel slows down performance of the method. Use only required channels.
page Integer false Page for pagination. Default: 1. Min: 1.
limit Integer false Limit of recordings per page. Default: 20. Min: 1. Max: 50.

Chats

Section describes how to save external chats' logs.

Save chat log

curl -i -X POST -H "Content-Type: application/json" --data-binary "@data.json" https://api.personaclick.com/chat_reports

# data.json for email
{
  "shop_id": "DvLWN2ZTMZ",
  "shop_secret": "EIxTuot8sj",
  "platform": "...",
  "code": "...",
  "email": "...",
  "data": {...}
}

# data.json for phone
{
  "shop_id": "DvLWN2ZTMZ",
  "shop_secret": "EIxTuot8sj",
  "code": "...",
  "platform": "...",
  "phone": "...",
  "data": {...}
}
// REST API only. See cURL.
// REST API only. See cURL.
// REST API only. See cURL.

Requirements

Endpoint: POST https://api.personaclick.com/chat_reports

Content type: form-data

Query Parameters

Parameter Type Required Description
shop_id String true Your API key
shop_secret String true Your API secret key
code String true Conversation unique code
platform String true Platform code. Supported: livetex
phone* String true User's phone number
email* String true User's email
data Object true Conversation raw data as stringified JSON object

Communications

Section describes how to save, read or edit external communication's logs.

Save communication log

curl -i -X POST -H "Content-Type: application/json" --data-binary "@data.json" https://api.personaclick.com/crm/client_calls

# data.json for phone
{
  "shop_id": "DvLWN2ZTMZ",
  "shop_secret": "EIxTuot8sj",
  "phone": "...",
  "channel": "...",
  "event": "...",
  "location_id": "...",
  "call_type": "...",
  "call_theme": "...",
  "comment": "...",
  "author_type": "...",
  "status": "..."
}

# data.json for email
{
  "shop_id": "DvLWN2ZTMZ",
  "shop_secret": "EIxTuot8sj",
  "email": "...",
  "channel": "...",
  "event": "...",
  "location_id": "...",
  "call_type": "...",
  "call_theme": "...",
  "comment": "...",
  "author_type": "...",
  "status": "..."
}

# data.json for did
{
  "shop_id": "DvLWN2ZTMZ",
  "shop_secret": "EIxTuot8sj",
  "did": "...",
  "channel": "...",
  "event": "...",
  "location_id": "...",
  "call_type": "...",
  "call_theme": "...",
  "comment": "...",
  "author_type": "...",
  "status": "..."
}
// REST API only. See cURL.
// REST API only. See cURL.
// REST API only. See cURL.
// REST API only. See cURL.

Requirements

Endpoint: POST https://api.personaclick.com/crm/client_calls

Content type: application/json

Query Parameters

Parameter Type Required Description
shop_id String true Your API key
shop_secret String true Your API secret key
phone* String true User's phone number
email* String true User's email
did* String true User's did
channel String true Сommunication's channel
event String true Сommunication's event
location_id String true Client's location id
call_type String true Сommunication's type
call_theme String true Сommunication's theme
subject_appeal String true Сommunication's subtheme
comment String true Сommunication's comment
author_type String true Сommunication's author
status String true Сommunication's status in external system

Read communication log

The query returns the last 20 communications as an array with items sorted by time

# Using phone as user identifier
curl https://api.personaclick.com/crm/client_calls?&shop_id=...&shop_secret=...phone=...

# Using email as user identifier
curl https://api.personaclick.com/crm/client_calls?&shop_id=...&shop_secret=...email=...

# Using did as user identifier
curl https://api.personaclick.com/crm/client_calls?&shop_id=...&shop_secret=...did=...
// REST API only. See cURL.
// REST API only. See cURL.
// REST API only. See cURL.
// REST API only. See cURL.

Requirements

Endpoint: GET https://api.personaclick.com/crm/client_calls

Query Parameters

Parameter Type Required Description
shop_id String true Your API key
shop_secret String true Your API secret key
phone* String true User's phone number
email* String true User's email
did* String true User's did

Edit communication log

The query returns the last 20 communications as an array with items sorted by time

# Using phone as user identifier
curl https://api.personaclick.com/crm/client_calls/ID?&shop_id=...&shop_secret=...phone=...

# Using email as user identifier
curl https://api.personaclick.com/crm/client_calls/ID?&shop_id=...&shop_secret=...email=...

# Using did as user identifier
curl https://api.personaclick.com/crm/client_calls/ID?&shop_id=...&shop_secret=...did=...
// REST API only. See cURL.
// REST API only. See cURL.
// REST API only. See cURL.
// REST API only. See cURL.

Requirements

Endpoint: PATCH https://api.personaclick.com/crm/client_calls

Query Parameters

Parameter Type Required Description
shop_id String true Your API key
shop_secret String true Your API secret key
phone* String true User's phone number
email* String true User's email
did* String true User's did
ID String true Communication's id
channel String true Сommunication's channel
event String true Сommunication's event
location_id String true Client's location id
call_type String true Сommunication's type
call_theme String true Сommunication's theme
subject_appeal String true Сommunication's subtheme
comment String true Сommunication's comment
author_type String true Сommunication's author
status String true Сommunication's status in external system

Reputation

Endpoints is used to work with shop's reputation.

Get reviews

curl -d "shop_id=SHOPID&count=COUNT&offset=OFFSET" https://api.personaclick.com/reputation/shop
// No implementation is needed in JS SDK
// No implementation is needed in iOS SDK
// No implementation is needed in Android SDK
// No implementation is needed in React Native SDK

This method overrides profile's settings.

Query Parameters

Parameter Type Required Description
shop_id String true Your API key
count String false Number of reviews
offset String false Offset of reviews

Stories

Section describes how to use Stories

Font setup

// Register the font family for Stories block first.
sdk.configuration().stories.registerFont(fileName: "Museo900", fileExtension: FontExtension.ttf.rawValue)
// You can customize font family, font size, colour's, icon size or any other view parameters of the Stories block to suit your app design.
// Each parameter is individual and may not be set - in this case default value's of SDK will be used.
sdk.configuration().stories.setStoriesBlock(fontName: "Museo",
                                            fontSize: 15.0,
                                            textColor: "#5ec169",
                                            textColorDarkMode: "#5ec169",
                                            backgroundColor: "#ffffff",
                                            backgroundColorDarkMode: "#000000",
                                            iconSize: 76,
                                            iconBorderWidth: 2.3,
                                            iconMarginX: 18,
                                            iconMarginBottom: 8,
                                            iconNotViewedBorderColor: "#fd7c50",
                                            iconNotViewedBorderColorDarkMode: "#fd7c50",
                                            iconViewedBorderColor: "#fdc2a1",
                                            iconViewedBorderColorDarkMode: "#fdc2a1",
                                            iconViewedTransparency: 1.0,
                                            iconAnimatedLoaderColor: "#5ec169",
                                            iconPlaceholderColor: "#d6d6d6",
                                            iconPlaceholderColorDarkMode: "#d6d6d6",
                                            iconDisplayFormatSquare: false,
                                            labelWidth: 76,
                                            pinColor: "#fd7c50",
                                            pinColorDarkMode: "#fd7c50",
                                            closeIconColor: "#5ec169")
// Set font family and font size for Default button on Story slide.
// Set font color and background color for Default button on Story slide.
sdk.configuration().stories.setSlideDefaultButton(fontName: "Museo",
                                                  fontSize: 17.0,
                                                  textColor: "#ffffff",
                                                  backgroundColor: "#5ec169",
                                                  textColorDarkMode: "#000000",
                                                  backgroundColorDarkMode: "#ffffff",
                                                  cornerRadius: 5)
// Set font family and font size for Products button on Story slide.
// Set font color and background color for Products button on Story slide.
sdk.configuration().stories.setSlideProductsButton(fontName: "Museo",
                                                   fontSize: 17.0,
                                                   textColor: "#ffffff",
                                                   backgroundColor: "#5ec169",
                                                   textColorDarkMode: "#000000",
                                                   backgroundColorDarkMode: "#ffffff",
                                                   cornerRadius: 5)
// Set the font family for the Products Card detailed view.
sdk.configuration().stories.setProductsCard(fontName: "Museo")
// Set the font family, font size, colour's for Banner with Promocode view.
sdk.configuration().stories.setPromocodeCard(productBannerFontName: "Museo",
                                             productTitleFontSize: 16.0,
                                             productTitleTextColor: "#5ec169",
                                             productTitleTextColorDarkMode: "#5ec169",
                                             productBannerOldPriceSectionFontColor: "#5ec169",
                                             productBannerPriceSectionFontColor: "#5ec169",
                                             productBannerPriceSectionBackgroundColor: "#ffffff",
                                             productBannerPromocodeSectionFontColor: "#ff0000",
                                             productBannerPromocodeSectionBackgroundColor: "#5ec169",
                                             productBannerDiscountSectionBackgroundColor: "#5ec169",
                                             productBannerPromocodeCopyToClipboardMessage: "Copied")
// Setup Stories block autoreload settings.
sdk.configuration().stories.storiesSlideReloadManually = false
sdk.configuration().stories.storiesSlideReloadTimeoutInterval = 10
sdk.configuration().stories.storiesSlideReloadIndicatorDisabled = false
sdk.configuration().stories.storiesSlideReloadIndicatorBackgroundColor = "#ffffff"
sdk.configuration().stories.storiesSlideReloadIndicatorSize = 76.0
sdk.configuration().stories.storiesSlideReloadIndicatorBorderLineWidth = 3
sdk.configuration().stories.storiesSlideReloadIndicatorSegmentCount = 9
sdk.configuration().stories.storiesSlideReloadIndicatorAnimationDuration = 1
sdk.configuration().stories.storiesSlideReloadIndicatorRotationDuration = 17
// Setup Stories Alert popup connection settings.
sdk.configuration().stories.storiesSlideReloadPopupMessageError = "Failed to retrieve data. Please check your connection and try again."
sdk.configuration().stories.storiesSlideReloadPopupMessageFontSize = 17.0
sdk.configuration().stories.storiesSlideReloadPopupMessageFontWeight = .medium
sdk.configuration().stories.storiesSlideReloadPopupMessageDisplayTime = 4
sdk.configuration().stories.storiesSlideReloadPopupPositionY = 120 //default constant
// Setup Stories Stories block text label characters wrapping settings.
sdk.configuration().stories.storiesBlockNumberOfLines = 2
sdk.configuration().stories.storiesBlockCharWrapping = false
sdk.configuration().stories.storiesBlockCharCountWrap = 15
StoriesView stories = findViewById(R.id.story_view);
stories.settings.label_font_size = 16;
stories.settings.label_font_family = Typeface.SERIF;
stories.settings.button_font_family = Typeface.MONOSPACE;
stories.settings.products_button_font_family = Typeface.DEFAULT_BOLD;

After initializing the SDK, you can set the desired style configuration for the fonts and buttons of the Stories block.

Before a font can be used, it must be registered with your app. Add the font file to your xCode project. You must specify a file name with .ttf or .otf extension. Сall the following method after SDK initialization for font registration

Available SDK Configuration options

You can use both the font family in the title and its direct name, for example with the "-Regular" suffix. The color must be transmitted in hex format, for example "#FFFFFF”. Any parameter in any method is optional, you can use both together and separately in combination with other parameters.

Utilities

Methods and helpers for finetune tasks.

Get current A/B segment

# No code implementation
//TBD
sdk->getCurrentSegment()
Personaсlick.getSegment()
// TBD

Returns user's segment for recommender blocks A/B-tests.

Errors

The PersonaClick API uses the following error codes:

Error Code Meaning
400 Bad Request -- Your request is invalid.
401 Unauthorized -- Your API key is wrong.
403 Forbidden -- The method is for internal use only or you don't have secret key to access it.
404 Not Found -- The specified object could not be found.
405 Method Not Allowed -- You tried to access with an invalid method.
406 Not Acceptable -- You requested a format that isn't json.
429 Too Many Requests -- You're sending too many requests.
500 Internal Server Error -- We had a problem with our server. Try again later.
503 Service Unavailable -- We're temporarily offline for maintenance. Please try again later.