Quick Links

Control Integration Guide

This integration guide includes a high-level overview of integration points, workflow, and detailed technical specifications for relevant SDKs and the corresponding API.

Device Data Collector

The Device Data Collector (DDC) gathers information from a end user's device by redirecting the device browser momentarily to Kount then back to the customer. This passive analysis conceals the Kount interaction with the customer and does not affect the end user's purchasing experience.

Use our guided Device Data Collector Content generator or follow the steps in the Native iOS and Android SDKs article.

Note: Data collection is made prior to making a POST to the Login API. The Device Data Collector uses the same session identifier as the subsequent login event to tie information together.


Device Data Collector browser recommendations

Proper placement and configuration of the browser Device Data Collector is crucial in gathering information to identify devices, adhere to business policies, and accurately define login risk. Incorrect placement or misconfiguration can cause limited or no data collection.

Page and Page Location

Place the Device Data Collector code in the body of the login page.

Kount reduces collection from the same session ID when a collection comes within 15 minutes. However, it is recommended that you run a single data collection per session. When multiple collections are run in a single session (if the collection was placed in the header, for example), it is possible the collection events can be mistaken as a DDOS attack, throttling all collections from your site.

Google Chrome Lazy Load

The Google Chrome “Lazy Load” feature defers loading images and iFrames that come below the fold of the page. This feature is active when the Chrome Data Saver feature is on and when the loading attribute is set to auto or unset.

If you’re using the Kount legacy data collector that utilizes an iFrame, update integration or set the loading attribute to eager, which bypasses lazy loading functionality.

Content Security Policy

Kount utilizes both third-party and first-party cookies as well as device data to identify devices. In order to take full advantage of the Device Data Collector, you might need to make modifications to the Content Security Policy on your site.

For more information on Content Security Policy, go to Content Security Policies (CSP) and the Device Data Collector.

API Endpoints

The Device Data Collector uses the Info, Login, Event, Trusted Device, and Secure MFA endpoints.

Info

Retrieve information data for a given customer and session.

Refer to the Info API help page for more information.

https://api.kount.com/info

Login

A request sent to Kount that triggers an evaluation of customer-defined policies and returns a decision based on those policies — refer to Control Login Event Workflow

Refer to the Login API help page for more information.

https://api.kount.com/login

New Account Opening

A New Account Opening request sent to Kount that triggers an evaluation of customer-defined policies and returns a decision based on those policies.

Refer to the New Account Opening API help page for more information.

https://api.kount.com/newaccountopening

Event

Provide information data for a given event.

Refer to the Event API help page for more information.

https://api.kount.com/events

Trusted Device

A request sent to Kount that creates a trusted device record for the specified user and the device associated to the session — refer to Control Trusted Device Workflow.

Refer to the Trusted Device API help page for more information.

https://api.kount.com/trusted-device

Secure MFA

A request sent to Kount that enables multi-factor authentication for the specified user and device associated with the session.

Refer to the Secure MFA API help page for more information.

https://api.kount.com/secure-mfa
Note: To access the sandbox API endpoints, add sandbox to the URL following this format:
https://api-sandbox.kount.com/[endpoint name]

API Authentication

  1. Kount will provide an API key and a temporary bearer token through encrypted email.
  2. Send an HTTP POST with the API key and temporary bearer token to the Sandbox or Production Auth Server URL.
  3. Receive a returned JSON that includes a special bearer token, as well as an expiration date provided in seconds in the form of an expires_in attribute.
    Note: Refresh the special bearer token before it expires, or the call to the API fails with a 401 Unauthorized message. Most tokens issued by login.kount.com expire after 20 minutes.

The API varies depending on if you are calling the Sandbox or Production system. The values are:

Environment Auth Server URL API URL
Sandbox

https://login.kount.com/oauth2/ausdppkujzCPQuIrY357/v1/token

 

https://portal-sandbox.kount.com/login

Production

https://login.kount.com/oauth2/ausdppksgrbyM0abp357/v1/token

https://portal.kount.com/login

Sample HTTP POSTs

Python
"""sandbox"""
import requests
AUTH_SERVER_URL = "https://login.kount.com/oauth2/ausdppkujzCPQuIrY357/v1/token"
API_URL = "https://api-sandbox.kount.com"
API_KEY = "YOUR API KEY HERE"
CLIENT_ID = "YOUR CLIENT_ID HERE"

r = requests.post(AUTH_SERVER_URL,
                  params={"grant_type": "client_credentials",
                          "scope": "k1_integration_api"},
                  headers={"Authorization": "Basic" + API_KEY,
                           "Content-Type":
                           "application/x-www-form-urlencoded"})

t = r.json()["access_token"]

r = requests.post(API_URL + "/login",
                  headers={'Authorization': "Bearer " + t},
                  json={
                    "clientId": "900900",
                    "sessionId": "d121ea2210434ffc8a90daff9cc97e76",
                    "userId": "meoyyd8za8jdmwfm",
                    "username": "meoyyd8za8jdmwfm",
                    "userPassword": "38401eb46f8fbb74c1846a5f47f68d83a9bef126b1d4143f886cd464323cdaab",
                    "userIp": "192.168.0.1",
                    "loginUrl": "http://www.example.com/login",
                    "userAuthenticationStatus": "true",
                    "userCreationDate": "2019-08-24T14:15:22Z",
                    "userType": "VIP",
                    "mfaPhone": "+12081234567",
                    "mfaEmail": "username@example.com",
                    "userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36",
                    "context": "LOGIN"
                })
print("Response:", r.json())
Typescript
const axios = require('axios')

const API = 'https://api-sandbox.kount.com'
const ISSUER = 
'https://login.kount.com/oauth2/ausdppkujzCPQuIrY357'
const CLIENT_ID = 'YOUR CLIENT ID HERE'
const API_KEY = 'YOUR API KEY HERE'

async function getBearerToken() {

    const auth = await axios({
        url: `${ISSUER}/v1/token`,
        method: 'post',
        headers: {
            authorization: `Basic ${API_KEY}`
        },
        params: {
            grant_type: 'client_credentials',
            scope: 'k1_integration_api'
        }
    })

    return auth.data.access_token
}

async function evaluateLogin(token: string) {

    const resp = await axios({
        url: `${API}/login`,
        method: 'post',
        headers: {
            authorization: `Bearer ${token}`,
        },
        data: {
            clientId: "900900",
            sessionId: "d121ea2210434ffc8a90daff9cc97e76",
            userId: "meoyyd8za8jdmwfm",
            username: "meoyyd8za8jdmwfm",
            userPassword: "38401eb46f8fbb74c1846a5f47f68d83a9bef126b1d4143f886cd464323cdaab",
            userIp: "192.168.0.1",
            loginUrl: "http://www.example.com/login",
            userAuthenticationStatus: "true",
            userCreationDate: "2019-08-24T14:15:22Z",
            userType: "VIP",
            mfaPhone: "+12081234567",
            mfaEmail: "username@example.com",
            userAgent: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36",
            context: "LOGIN"
        }
    })

    return resp.data
}
const main = async () = {
    const token = await getBearerToken();
    const resp = await evaluateLogin(token);
    console.log(JSON.stringify(resp, null, 4))
}

main()
GoLang
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
)

type config struct {
	API      string
	Issuer   string
	ClientId string
	APIKey   string
}

func getToken(c *http.Client, issuer, creds string) string {

	req, _ := http.NewRequest(http.MethodPost, issuer+"/v1/token", nil)

	req.Header.Add("Authorization", "Basic "+creds)

	req.Header.Add("Content-Type", "application/x-www-form-urlencoded")

	q := req.URL.Query()
	q.Add("grant_type", "client_credentials")
	q.Add("scope", "k1_integration_api")
	req.URL.RawQuery = q.Encode()

	resp, _ := c.Do(req)
	defer resp.Body.Close()

	t := struct {
		TokenType   string `json:"token_type"`
		ExpiresIn   int    `json:"expires_in"`
		AccessToken string `json:"access_token"`
	}{}

	json.NewDecoder(resp.Body).Decode(&t)
	return t.AccessToken
}

func evaluate(c *http.Client, api string, payload LoginRequest, token string) string {

	j, _ := json.Marshal(payload)

	req, _ := http.NewRequest(http.MethodPost, api+"/login", bytes.NewBuffer(j))

	req.Header.Add("Authorization", "Bearer "+token)

	resp, _ := c.Do(req)
	defer resp.Body.Close()

	b, _ := io.ReadAll(resp.Body)
	s := string(b)
	return s
}

type LoginRequest struct {
	ClientID                 string `json:"clientId"`
	SessionID                string `json:"sessionId"`
	UserID                   string `json:"userId"`
	Username                 string `json:"username"`
	UserPassword             string `json:"userPassword"`
	UserIP                   string `json:"userIp"`
	LoginURL                 string `json:"loginUrl"`
	UserAuthenticationStatus string `json:"userAuthenticationStatus"`
	UserCreationDate         string `json:"userCreationDate"`
	UserType                 string `json:"userType"`
	MFAPhone                 string `json:"mfaPhone"`
	MFAEmail                 string `json:"mfaEmail"`
	UserAgent                string `json:"userAgent"`
	Context                  string `json:"context"`
}

func main() {
	config := config{
		API:      "https://api-sandbox.kount.com",
		Issuer:   "https://login.kount.com/oauth2/ausdppkujzCPQuIrY357",
		ClientId: "",
		APIKey:   "",
	}
	client := &http.Client{}
	token := getToken(client, config.Issuer, config.APIKey)

	payload := LoginRequest{
		ClientID:                 config.ClientId,
		SessionID:                "d121ea2210434ffc8a90daff9cc97e76",
		UserID:                   "meoyyd8za8jdmwfm",
		Username:                 "meoyyd8za8jdmwfm",
		UserPassword:             "38401eb46f8fbb74c1846a5f47f68d83a9bef126b1d4143f886cd464323cdaab",
		UserIP:                   "192.168.0.1",
		LoginURL:                 "http://www.example.com/login",
		UserAuthenticationStatus: "true",
		UserCreationDate:         "2019-08-24T14:15:22Z",
		UserType:                 "VIP",
		MFAPhone:                 "+12081234567",
		MFAEmail:                 "username@example.com",
		UserAgent:                "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36",
		Context:                  "LOGIN",
	}

	resp := evaluate(client, config.API, payload, token)
	fmt.Printf("%s\n", resp)
}
Bash
#!/usr/bin/env bash

API='https://api-sandbox.kount.com'
ISSUER='https://login.kount.com/oauth2/ausdppkujzCPQuIrY357'
CLIENT_ID=''
API_KEY=''

# Get our token (it is valid for 20 minutes)
RESPONSE=$(curl -s -X POST "${ISSUER}/v1/token?grant_type=client_credentials&scope=k1_integration_api" -H "Authorization: Basic ${API_KEY}" -H "Content-Type: application/x-www-form-urlencoded")
TOKEN=$(echo $RESPONSE | jq -r .access_token)

# Make our evaluation request
REQUEST_DATA='{
                "clientId": "900900",
                "sessionId": "d121ea2210434ffc8a90daff9cc97e76",
                "userId": "meoyyd8za8jdmwfm",
                "username": "meoyyd8za8jdmwfm",
                "userPassword": "38401eb46f8fbb74c1846a5f47f68d83a9bef126b1d4143f886cd464323cdaab",
                "userIp": "192.168.0.1",
                "loginUrl": "http://www.example.com/login",
                "userAuthenticationStatus": "true",
                "userCreationDate": "2019-08-24T14:15:22Z",
                "userType": "VIP",
                "mfaPhone": "+12081234567",
                "mfaEmail": "username@example.com",
                "userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36",
                "context": "LOGIN"
              }'
RESPONSE=$(curl -s -X POST ${API}/login -H "Authorization: Bearer ${TOKEN}" -d "$REQUEST_DATA")
echo "$RESPONSE" | jq

Environments

Kount Control has two environments for integration:

  • Sandbox — Full integration with test data
  • Production — Full integration with Production data

Valid customer identification (clientID) and JWT credentials are required to make a call to any of the API endpoints (JWT credentials are not required for device data collection). These credentials are provided as part of technical integration.

Sandbox Environment 

The Sandbox environment is intended for user setup and integration testing. It includes a user interface so fraud analysts can set Profiles and Policies, research login event history, and run reports. It also includes all functionality of the current Production environment; however, it is not scalable like the Production environment.

Production Environment

The Production Environment is designed to handle full-scale production traffic.

Parameterizing

While we strive to prevent breaking changes to the API endpoints, if it does occur, the version of API endpoint will increment.

dataCollectionHost

It is important to use the proper data collection host to ensure that sessions are properly aligned between data collection and login requests.

  • Sandbox: dataCollectionHost = “https://tst.kaptcha.com”
  • Production: dataCollectionHost = “https://ssl.kaptcha.com”
Was this article helpful?
0 out of 0 found this helpful