Simility API Documentation
Fraud Detection That Adapts and Scales
Fraud Detection That Adapts and Scales
The Simility application is a software platform for detecting spam, fraud and member abuse. You can send us data about your users and their activity and we will tell you the risk that user is committing fraud. The processing and decisioning is visible on your Simility dashboard at app.simility.com.
This API documentation is broken into three sections:
You need an account with Simility in order to use our service. Upon signup we will provide with your a customer_id (e.g microinc1) which will be unique to your company. Please contact us and we'll set you up.
Device Recon is a script that runs on your website or mobile app and collects characteristics about your users' devices (PC, tablets, and phones), such as browser, operating system, device hardware, and user behavior. Simility uses these characteristics to determine the riskiness of the device and the user.
Below are 4 types of JavaScript integration. Choose the one that best serves your needs and paste the corresponding JavaScript snippet in the <body>
section of specific pages on your website.
<script>
var similityContext = {
"customer_id": "microcorpinc1" //required; provided to you by Simility during signup
};
</script>
<script type="application/javascript" src="https://cdn.simility.com/b.js"></script>
<script>
var similityContext = {
"customer_id": "microcorpinc1", //required; provided to you by simility during signup
"session_id": your.page.session.id.variable, // recommended; unique per user session, typically persistent by your backend
"user_id": your.page.user.id.variable, // recommended; user_is variable from your session, typically persistent on your backend
};
</script>
<script type="application/javascript" src="https://cdn.simility.com/b.js"></script>
session_id, user_id - We strongly recommend you set the user_id and/or session_id variables that are persistent on your backend. This is the default way to join the frontend device data with your backend transactions user data that you might send to Simility (See the Upload section below).
"session_id": your.page.session.id.variable
Use this setup when sending custom data in addition to device data, e.g. User or Transaction data. The data is collected when the web page loads.
<script>
var similityContext = {
"customer_id": "microcorpinc1", // required; customer_id is provided by Simility during signup
"session_id": your.page.session.id.variable, // recommended; your user session id variable
"user_id" : your.user.id.variable, // optional; if your user is logged in this could be the user id or email id
"simility_lite": true, // optional; true by default
"transaction_info": [{ // optional; additional data associated with this session
"entity": "orders", // required if sending transaction_info; entity type of this data
"id": "order1001", // required if sending transaction_info; unique id of transaction data
"fields": { // required if sending transaction_info; can contain any ad hoc payload data about this order (or user)
"first_name": "John",
"last_name": "Doe",
"user_id": "user2321",
"email": "johndoe@somedomain.pr",
"order_categories": ["210", "334", "213"],
"order_details": { "is_first_order": true, "num_retries": 2 },
"cart_total": 203.44
}
}]
};
</script>
<script type="application/javascript" src="https://cdn.simility.com/b.js"></script>
The transaction_info field contains any additional payload you choose to send. The only required elements here are entity and id. You can send any ad hoc JSON inside the fields sections. We are very flexible in what we can accept and recommend sending existing variables from your current data flows inside the fields section.
e.g. For a SignUp or Login page you can send user payload, with id = userid or email.
e.g. For a CheckOut page you can send OrderTransaction data with id = transaction id.
You can send any complex payload with multiple entities and nested data.
"entity": "orders" // entity type of this payload. e.g. user, orders, transactions, applications, profile, etc.
"id": "order1001", // unique id of this data payload, e.g. orderid, userid, emailid, etc.
"fields": { // actual payload for this additional data
"first_name": "John",
"last_name": "Doe" //...Any complex nested JSON could be sent here
}
simility_lite This is true by default. If set to false, we request some additional information from your customers, like geo-location, mouse movements, etc.
Please discuss with our support team if you'd like to understand the full details of this setting.
"simility_lite": true
Use this setup if you want to trigger device data collection on an event, like a button click, instead of on page load. This allows Simility to collect data your customers enter into fields on your web page.
In this example, the customer fills out fields on your web page with their first name, email, and a cart total, then clicks Checkout. The values in these fields are passed to the Simility script when the customer clicks the Checkout button. This is a popular setup when using a single page application.
<form>
First Name: <input type="text" name="f-name">
Email: <input type="text" name="email">
Cart Total: <input type="number" name="grand-total">
</form>
<button id="checkout-button">Checkout</button>
Example JavaScript code to add just before the closing </body>
tag on your webpage where you are collecting data:
<script>
$('#checkout-button').click(function() {
if (window.SimilityScript) {
var d = document;
var first_name = d.getElementsByName("f-name")[0].value;
var cart_total = d.getElementsByName("grand-total")[0].value;
var similityContext = {
"customer_id": "microcorp1",
"session_id": your.page.session.id.variable,
"simility_lite": true,
"transaction_info": [{
"entity": "orders",
"id": "AA1001",
"fields": {
"first_name": first_name,
"cart_total": cart_total
//... additional custom data fields
}
}]
};
var ss = new SimilityScript(similityContext);
ss.execute();
}
});
</script>
<script type="application/javascript" src="https://cdn.simility.com/b.js" data-autoexecute="false"></script>
If you have already defined window.similityContext
along with applicable parameters and don’t want to change parameters later, you do not need to pass similityContext
:
<script>
$('#confirmOrder').click(function() {
if (window.SimilityScript) {
var ss = new SimilityScript();
ss.execute();
}
});
</script>
If you prefer to populate the fields and send to Simility automatically without an event such as a click function, remove the .click
function in the previous example and change data-autoexecute
to "true"
:
<script type="application/javascript" src="https://cdn.simility.com/b.js" data-autoexecute="true"></script>
Simility’s iOS API allows you to collect data for fraud detection from your iOS application. Once this API is invoked, it will collect data and send to our server asynchronously in a background thread without affecting any user interface operations. Simility will provide two artifacts: the header file SimilityBeacon.h and Cocoa touch static library libSimilityBeacon.a.
You should link Foundation, UIKit, CoreTelephony, Security and CommonCrypto Frameworks/Lib if they are not already being used in your application. You also need to link AdSupport framework as well if your app is serving advertisements.
+ (void) initBeacon:(NSString *) customerId sessionId:(NSString *) sessionId;
+ (void) initBeacon:(NSString *) customerId sessionId:(NSString *) sessionId userId:(NSString *) userId;
+ (void) initBeacon:(NSString *) customerId sessionId:(NSString *) sessionId userId:(NSString *) userId metadata:(NSDictionary *) metadata;
+ (void) initBeacon:(NSString *) customerId sessionId:(NSString *) sessionId userId:(NSString *) userId metadata:(NSDictionary *) metadata requestEndpoint:(NSString *) requestEndpoint;
+ (void)initBeacon:(NSString *) customerId sessionId:(NSString *) sessionId userId:(NSString *) userId metadata:(NSDictionary *) metadata transactionInfo:(NSString *)transactionInfo;
+ (void)initBeacon:(NSString *) customerId sessionId:(NSString *) sessionId userId:(NSString *) userId metadata:(NSDictionary *) metadata transactionInfo:(NSString *)transactionInfo requestEndpoint:(NSString *) requestEndpoint;
+ (void) initBeacon:(NSString *) customerId sessionId:(NSString *) sessionId userId:(NSString *) userId metadata:(NSDictionary *) metadata transactionSubCustomerId:(NSString *) transactionSubCustomerId transactionInfo:(NSString *) transactionInfo;
+ (void) initBeacon:(NSString *) customerId sessionId:(NSString *) sessionId userId:(NSString *) userId metadata:(NSDictionary *) metadata transactionSubCustomerId:(NSString *) transactionSubCustomerId transactionInfo:(NSString *) transactionInfo requestEndpoint:(NSString *) requestEndpoint;
Sample code for calling the Simility API:
#import "ViewController.h"
#import "SimilityBeacon.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSDictionary *metadata = @{@"orderId" : @"order_no_8765456"};
NSString *customerId = @"customer_id_issued_by_simility";
[SimilityBeacon initBeacon:customerId sessionId:@"cae1234567" userId:@"user1" metadata:metadata];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
Sample code for calling the Simility API:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let customerId = "customer_id_issued_by_simility"
let metadata = ["order_id":"order_no_865432"]
SimilityBeacon.initBeacon(customerId, sessionId: "cae876543", userId: "user1", metadata: metadata)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Simility’s Android API allows you to collect data for fraud detection from your Android application. Simility will provide a prebuilt file called beacon_sdk.jar. As soon as a client triggers Simility’s API, it will compute signals in the background without affecting any UI operations. Signals are collected on the basis of Manifest permissions in the host Application.
public static void initBeacon(Context context, String customerId, String sessionId)
public static void initBeacon(Context context, String customerId, String sessionId, String userId)
public static void initBeacon(Context context, String customerId, String sessionId, String userId, Map<String, String> metadata)
public static void initBeacon(Context context, String customerId, String sessionId, String userId, Map<String, String> metadata, String requestEndpoint)
public static void initBeacon(Context context, String customerId, String sessionId, String userId, Map<String, String> metadata, String transactionSubCustomerId, String transactionInfo)
public static void initBeacon(Context context, String customerId, String sessionId, String userId, Map<String, String> metadata, String transactionSubCustomerId, String transactionInfo, String requestEndpoint)
Sample code for calling the Simility API:
package com.example.androidintegratiodemo;
import java.util.HashMap;
import java.util.Map;
import com.simility.beacon.SimilityBeacon;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String customerId = "your_simility_customer_id";
Map<String, String> metadata = new HashMap<String, String>();
metadata.put("order_id", "order_no_8765542");
SimilityBeacon.initBeacon(getApplicationContext(), customerId, "cae8765432", "user1", metadata);
}
}
Sample code for the class extending DroidGap
package com.simility.phonegaptestapp;
import org.apache.cordova.DroidGap;
import com.simility.beacon.SimilityBeacon;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
public class MainActivity extends DroidGap/*Activity*/ {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.init();
super.appView.addJavascriptInterface(this, "MainActivity");
super.loadUrl("file:///android_asset/www/index.html");
}
@JavascriptInterface
public void callSimilityBeacon() {
String customerId = "your_simility_customer_id";
Map<String, String> metadata = new HashMap<String, String>();
metadata.put("order_id", "order_no_8765542");
SimilityBeacon.initBeacon(super.getActivity(), customerId, "cae8765432", "user1", metadata);
}
}
Sample code on HTML page to call Simility API
<!DOCTYPE HTML>
<html>
<head>
<title>Sample</title>
<script type="text/javascript" charset="utf-8" src="cordova-2.0.0.js"></script>
</head>
<body>
<h1>PhoneGap Sample App</h1>
<script type="text/javascript">
(function(){
window.MainActivity.callSimilityBeacon();
})();
</script>
</body>
</html>
You can send data to Simility via -
Our DeviceRecon collects device data for browser, iOS and Android devices. In addition to collecting device data you can use the beacon JS snippet to send additional data from frontend to Simility. This additional data can be packaged in the trasnactionInfo object which is available on JS Web, Adnroid or iOS integration. Please refer to the Device Recon Integration.
Simility backend API is flexible to handle custom JSON objects, including arrays and objects within your data object. Simility backend schema is flexible and the json payload can be customized as per your requirements.
We recommend using a JSON validator to make sure your JSON file is formatted properly. After you post some data, you can check whether it uploaded successfully by running a SQL query in your Simility app to search for it.
Substitute the customer_id and entity params in the POST URI and the "id" values with the EntityId in the json payload.
Headers
Content-Type: application/json
Authorization: Bearer [token]
POST: /server/rest/ingress/$customer_id$/$entity$
e.g. https://app.simility.com/server/rest/ingress/microcorp1/user
Body
[
{
"id": "AA1001",
"entity": "user",
"fields": {
"first_name": "John",
"account_age": 18,
"interests": ["snowboarding", "hiking", "fishing"],
"quality_status": {
"0": "active",
"1": "good",
"2": "inactive",
"3": "malicious"
}
}
}
]
You can also send data for multiple records of the same entities or multiple entities in the same POST call. For example, if you want to send information about users and orders, leave the entity names out of your URI and put them in the data object.
In this example JSON object, we'll upload data values for the id and user entity, so leave entity name out of the URL. Again, we've populated some random example data in the fields key:
Headers
Content-Type: application/json
Authorization: Bearer [token]
POST: /server/rest/ingress/$customer_id$
Body
[
{
"entity": "user",
"id": "AA1001",
"fields": {
"first_name": "John",
"account_age": 18,
"interests": ["snowboarding", "hiking", "fishing"],
"quality_status": {
"0": "active",
"1": "good",
"2": "inactive",
"3": "malicious"
}
}
},
{
"entity": "order",
"id": "BB901",
"fields": {
"cart_items": 4,
"cart_total": 14.10
}
},
{
"entity": "order",
"id": "BB902",
"fields": {
"cart_items": 34,
"cart_total": 13.90
}
}
...
]
Response Please refer to the section below on getting decisions from Simility for more details.
Depending on how your pipeline is setup on the Simility side (Asynchronous or Synchronous) you will get specific response back
Asynchronous
Here you will get an immediately acknowledgement from Simility backend that we received the data and a HTTP 200OK message is send as RESPONSE to the POST REQUEST. Subsequently once the transaction is processed and decision is made Simility will post the response on your webhook url listener asynchronous.
HTTP/1.1 200 OK
Synchronous
Simility will send a RESPONSE to your POST REQUEST with a decision message payload. Please refer to the section below on getting decisions from Simility for more details.
{
"type": "decision",
"entries": [
{
"id": "ABC12345",
"entity": "order",
"decisionLabels": ["Not Fraud", "Active User"],
"score": -41,
"leadLabels": {
"LowZipcodeCategoryVariability": -22,
"HighRegisteredIPFirstVoucherRatio": -19
},
"note": "Talked to customer on the phone, verified identity",
"queue": "Suspicious Orders",
"timestamp": "2015-12-01 01:10:50",
"decisionBy": "analyst_one@prudentcompany.com"
}
]
}
When sending data via DataAPI every event you send triggers a evaluation from simility and a decision is made In normal operations, your data would not have a fraud decision yet when you are uploading it to Simility,
but we do allow you to upload decisions in case you have fraud decisions already on historical data. e.g. you want to show Simility which cases you have already blacklisted or whitelisted.
Check out the decision labels in your Simility app to see the decisions available to you.
Then you can add "decision"
as a parameter within "fields": {}
with the corresponding value, e.g. "Blacklist"
:
Headers
Content-Type: application/json
Authorization: Bearer [token]
POST: /server/rest/ingress/update/$customer_id$/$entity$
[
{
"id": "10000",
"fields": {
"decision": "Approved",
},
"entity": "user"
}
]
Optionally you can send fields in additional to the required "decision" field which will again update the entity data.
[
{
"id": "A10001",
"entity": "user",
"fields": {
"decision": "Fraud",
"fname": "John",
"lname": "Doe",
"email": "jd@simility.com",
"ip": "127.0.0.2",
"decisionBy" : "Autoscript"
}
}
]
You can visit Simility File Upload Tool from the UI to upload CSV files.
Simility's Data APIs allows you to get data from Simility backend - Decision, Labels, Scores, Features et. al. The response comes as a JSON object. Your analysts can create and edit these fraud decisions labels and workflow logic in Simility UI console Simility app in Tools > Label Viewer.
You can get data (decisions, labels, raw data) from Simility via -
{
"type": "decision",
"entries": [
{
"id": "ABC12345",
"entity": "order",
"decisionLabels": ["Not Fraud", "Active User"],
"score": -41,
"leadLabels": {
"LowZipcodeCategoryVariability": -22,
"HighRegisteredIPFirstVoucherRatio": -19
},
"note": "Talked to customer on the phone, verified identity",
"queue": "Suspicious Orders",
"timestamp": "2015-12-01 01:10:50",
"decisionBy": "analyst_one@prudentcompany.com"
}
]
}
You need to implement a webhook/ REST JSON listener which can consume Simility Decision JSON Message.
Please share the URL endpoint with Simility when the listener is available along with any specific Auth mechanisms you want to implement (e.g. Bearer token). Please discuss with Simility support team on the response times to expect and the timeouts to set for this mode.
In this case the Simility Decision payload is sent as a RESPONSE to the upload POST request when data is received. This was the customer gets decisions on every event they send on the same request. Please discuss with Simility support team on the response times to expect and the timeouts to set for this mode.
"type": "decision"
, since you are pulling decisions.Specific Id
GET: /server/rest/decision/$customer_id$/$entity_name$?id=ABC12345
Response:
{
"type": "decision",
"entries": [
{
"id": "ABC12345",
"entity": "order",
"decisionLabels": ["Not Fraud", "Active User"],
"score": -41,
"leadLabels": {
"LowZipcodeCategoryVariability": -22,
"HighRegisteredIPFirstVoucherRatio": -19
},
"note": "Talked to customer on the phone, verified identity",
"queue": "Suspicious Orders",
"timestamp": "2015-12-01 01:10:50",
"decisionBy": "analyst_one@prudentcompany.com"
}
]
}
Specific Date Range:
GET: /server/rest/decision/$customer_id$/$entity$?startDate=2012-10-01&endDate=2012-10-31
Response:
{
"type": "decision",
"entries": [
{
"id": "ABC12345",
"entity": "order",
"decisionLabels": ["Not Fraud", "Active User"],
"score": -24,
"leadLabels": {
"BillingShippingAddressMatch": 7,
"NotFirstOrder": 10,
"HighRegisteredIPFirstVoucherRatio": -19,
"LowZipcodeCategoryVariability": -22
},
"note": "Talked to customer on the phone, verified identity",
"queue": "Suspicious Orders",
"timestamp": "2012-10-01 01:10:50",
"decisionBy": "analyst_one@prudentcompany.com"
},
{
"id": "ABC12346",
"entity": "order",
"decisionLabels": ["Fraud", "Spammer"],
"score": -58,
"leadLabels": {
"LowZipcodeCategoryVariability": -22,
"HighKeyboardVelocity": -17,
"HighRegisteredIPFirstVoucherRatio": -19
},
"note": "Block account permanently",
"queue": "Suspicious Orders",
"timestamp": "2012-10-01 01:12:08",
"decisionBy": "analyst_two@prudentcompany.com"
}
...
]
}