NAV
cURL Java JavaScript PHP Scala C#

Introduction

The Clutch platform provides developers with the ability to integrate through the JSON API.

This document will guide you through implementing a connection between the JSON API and your point of sale, website, shopping cart or any other service you might want to provide, where loyalty and/or gift functionality is being presented to your customer.

Loyalty

The Clutch loyalty engine does all the heavy lifting and computation, enabling your application to focus simply on recording checkouts, retrieving customer account information and redeeming rewards, among other actions.

At a high level, you will record checkouts into the Clutch platform, which will track all customer activity and perform actions specific to each customer, such as issuing rewards and sending notifications. You can choose to have rewards redeemed immediately in the form of calculated discounts, during the next checkout as a discount or you can place your own API calls to redeem balance whenever this fits into your process most optimally.

The business logic responsible for issuing points, giving discounts, etc is defined in Campaigns, which can be configured through the Clutch Portal.

Gift & Stored Value

In addition to loyalty services, the Clutch platform also provides the ability to manage gift, store credit, pre-paid or reloadable card services. You can issue or redeem balance for a customer using the API, as well as search for customers and perform balance inquiries. In addition, you can also reserve balance using ‘holds’ on any amount of card balance and use or release this hold later.

One card can hold any configurable number of balances at the same time. The same card could hold USD balance, but also Points and 'Coffee Points’ or any custom value type you want to set up.

Tools

There are a number of tools available alongside the JSON API that can help you get started and configure everything for your brand.

Portal Access

Contact Clutch support to get access to the portal, you can contact asksupport@clutch.com to get started.

You will receive 2 logins, one for the stage portal where you can test everything out and one for the production portal, where all your real data will be configured:

Generating API Credentials

Internal (Clutch) Developers

Once you have access to the Portal, you can log in and generate an API Key / Secret pair, which you will need to place any API calls. If you are not a Clutch developer, you must contact asksupport@clutch.com.

To obtain a new API Key / Secret:

  1. Sign in to the Portal (stage or production, depending on where you want to use the API keys)
  2. In the left navigation, go to Admin > API Credentials
  3. In the top-right corner, press the green button for “New API Key”
  4. A pop-up will be displayed with the new API Key and the API Secret. Copy both of these now and retain them in a secure location, as the API Secret will get encrypted in the next step and will then be irretrievable for security reasons.
  5. Press the Save button, then the Close button.

External Developers

Contact asksupport@clutch.com for credentials to be issued to you

Sandbox access

Example request body for Search:

{
  "filters": {}
}

Once you have your API Key and Secret, you will be ready to start testing out some API calls. When testing, make sure to keep these details on hand:

  1. Your API Key / Secret for stage or for production
  2. Your brand ID
  3. Your test location ID
  4. Your test terminal ID

You will receive your brand, location and terminal IDs from Clutch support once you get started. If you did not get them, contact asksupport@clutch.com.

There are 2 places to get started, either use the Sandbox at the bottom of this document, or use the Sandbox in the Portal.

Sandbox in this document

Go to the Sandbox in this document, it will explain how to use it.

Sandbox in the Portal

You can also use the sandbox in the Portal, which is a standard Swagger.io sandbox. To access it:

  1. Sign in to the Portal (stage or production, depending on where you want to test out your requests)
  2. In the left navigation, go to Documentation > JSON API Sandbox.
  3. Enter you API Key and Secret and hit the button.
  4. The lower area of your page should now be populated. You can expand this section by clicking on it and click on any of the API methods to try them out.

Definitions

Hierarchical overview of basic terms in Clutch.

Brand

Your brand is the highest object in the hierarchy of definitions. You will typically have a single brand, and set up all your store locations, groups of store locations, employees, cards, etc under this brand. All objects within your brand belong strictly to that brand and can never be used outside of the brand.

Groups

Under your brand, you can set up any number of store location groups. By default, you will just have one group with all your store locations. However, if your brand has several subdivisions, you can choose to break up your store locations into multiple groups. Per location group, you can set up Clutch Portal logins with restricted access and get reports / statistics about all activity limited to the group’s store locations.

Portal logins

You can log in to the Clutch Portal for the production environment, or use the Clutch Stage Portal to get started in a test environment. A Portal login can be restricted to a group or a specific location.

Locations

A location represents either a physical brick and mortar store location, a website or anything describing a venue where customers can interact with a Point of Sale device.

Terminals

A Terminal object represents a Point of Sale device, used to indicate where an API call is originating from. In case of brick and mortar store locations, it would make sense to set up one Terminal object per physical Point of Sale device / cash register. For online environments, you would usually just set up a single Terminal object.

A Terminal object is always tied to one location.

Employees

An employee object represents an employee working at one specific location. You can specify an employee on every request and optionally require employees to use a PIN / password to perform any action through the JSON API. See the Employee Identification section for more information.

Programs

A program can be used to group one or more card sets, which in turn contain the individual cards. Per program you can configure some settings that you want to apply to all card sets associated with the program.

You can use a program as a logical grouping of multiple card sets that should all follow the same behaviour.

Value types

A value type is a description of a type of balance that is available to all cards of all card sets within one program. A value type is defined by its program, balanceType and depending on the balanceType optionally also a balanceCode.

Available balanceTypes are:

Per value type, you can configure the maximum balance you want any card to have of this value type and the minimum and maximum issuance and redemptions amounts. You can use this functionality to for instance limits gift cards in a specific program to have at most $100 on them.

You can set up Currency value types with international currency codes, such as USD. If the balanceType is custom, you can build out as many custom value types with custom balanceCodes as you want. You can use these custom value types to maintain balances specific to your brand, perhaps CoffeePoints or LifetimePoints. You can also use custom value types in combination with Campaigns to act as ‘counters’.

Card sets

A card set is a set of individual cards. If you have 10,000 physical giftcards, this could for instance be one card set. When placing a Card Allocation API method, you can allocate one card from a card set that you have set up.

In itself a card set does not have any configurable options, it mainly acts as a logical grouping of some cards.

Cards

Individual cards are the core object within the Clutch platform. You can use a card number to link customer data with, issue balances on it, or attach third party usernames to it.

One card can hold a multitude of balances, but at most one per value type that is configured for the program to which the card’s card set belongs.

A card always has a unique card number, which is what it’s identified with within the Clutch Platform. In addition, you can assign a custom card number to each card, which can then be used to search matching cards.

Card balances

Every card can have 0 or more card balances, at most one per value type set up for the program to which the card’s card set belongs.

Card balance can be configured to be expiring, it can be flagged as return-related balance (i.e. store credit) and you can place reservations on it.

Customer demographics

Every card can have a primary customer and even an alternate customer associate with it. On each of these customer objects, you can store some basic demographical data. For more information about saving demographical data on a card object, see Updating Card Information. You can also use a limited number of demographical fields from the primary customer object associated with a card to search matchhing cards. See the Searching Cards section for more information.

In addition to the basic demographical fields that are available, you can also store any custom card data you want on a card, see the Custom card data section for more information.

Coupon Sets

Coupon sets are groups of coupons that can be used to run promotions or discounts. It is possible to load coupon sets or autogenerate a set of coupons and coupon sets can optionally be expanded at a later point if it is depleted or getting close.

When allocating a new coupon for a customer, you have to select a coupon set to allocate from and a coupon will be picked from this set at random.

Coupons

A coupon is a one-time use object with a unique code (i.e. coupon ID). The coupon can optionally be restricted to only work with one or more cards and it can optionally be tagged with a set of tags. These tags can be defined both during the initial coupon bulk load process, during coupon allocation or at any point using an API call.

Coupons can be flagged as used or unused manually through API calls, or this process can be automated as part of campaigns. During checkout API calls, you can specify 0..n coupons and in your campaigns you can configure coupons to be a condition or a result. You could for instance specify that you only get a discount of $10.00 if you are using a coupon from coupon set X or you could configure the campaign to allocate a new random coupon from coupon set Y if a customer spends more than $100.00.

Customer segment definitions

In the Clutch Portal, you can define a customer segment and run this 'query’ on your customer base. You could for instance use this to split your customers into a low-value and high-value segment and set up Campaigns intended to migrate your customers from a low-value to a high-value segment.

API credentials

To access the JSON API, you need API credentials, being an API Key and a matching API Secret. You can manage your API Keys in your brand’s portal. By default an API Key / secret pair can be used to perform any operation within your brand.

Clutch will only store your API key, and a 'hash’ of your secret. Your actual API secret can only be shown once when it is generated in the Clutch Portal. For security reasons, Clutch will not keep a record of the plain-text version of your API secrets.

Request basics

The JSON API is based on Swagger.io version 1.2. This means that the entire API is described through JSON files, accepts JSON as input and will show JSON as output. The main Swagger.io api-docs file is located at https://api.clutch.com/api-docs, which links to the more detailed https://api.clutch.com/api-docs/merchant where all main API methods are documented.

There are many API client code-generators in existance for Swagger.io APIs, for more information see: http://swagger.io.

Endpoints

The base endpoint to be used for all API calles is:

Each API method is available by suffixing the base URL with the method name. For instance, the endpoint for search requests in production is: https://api.clutch.com/merchant/search.

All endpoints accept HTTP POST requests only.

Authentication

If you just open https://api.clutch.com/merchant/search in a browser, the request will fail, as it will be missing its authentication headers. Every API request must have at least 4 headers for authentication and identification:

  1. Header Authorization, for HTTP Basic authentication using your API key and API secret as uesrname and password.
  2. Header Brand, for your brand ID. This is needed for authentication, as your API key exists within your brand.
  3. Header Location, for your location ID. This is used to identify where the request is coming from.
  4. Header Terminal, for your terminal ID. This is used to identify which terminal / Point of Sale the request is coming from.

Authorization header

The Authorization header should have a value in the form: Basic dXNlcjpwYXNz. It starts with the string Basic followed by a base64-encoded API Key:API Secret. If your API Key is user and your API Secret is pass, you would have to base64-encode the string user:pass, resulting in dXNlcjpwYXNz.

For more information about HTTP Basic authentication, see: http://www.w3.org/Protocols/HTTP/1.0/spec.html#BasicAA.

Additional headers

Besides the headers for authentication, you can optionally also send in the following headers:

  1. Header externalTransactionId, custom request identifier for logging. See Listing Requests.
  2. Header customRequestId, custom request deduplication identifier. See Idempotence.
  3. Header note, can contain a short reference or custom classification code for the request.

Note header

The note header does not have a constraint on uniqueness. If needed, every single API call could share the same note value. This value is not searchable or reportable, it will only show up in the requestLookup API call response.

Placing requests

Example request:

curl https://api-stage.clutch.com/merchant/search -X POST \
   -u "API_KEY:API_SECRET" \
   -H "brand: BRAND_ID" \
   -H "location: LOCATION_ID" \
   -H "terminal: TERMINAL_ID" \
   -d '{"filters":{}}'
{"filters":{}}
/* 
 * NOTE: Not intended for usage in a customer's webbrowser,
 * only intended for JS-based server software such as node.js.
 */

var apiKey = "";
var apiSecret = "";
var brandId = "";
var locationId = "";
var terminalId = "";

var beforeSend = function(request) {
  request.setRequestHeader("Authorization", "Basic " + btoa(apiKey + ":" + apiSecret));
  request.setRequestHeader("Brand", brandId);
  request.setRequestHeader("Location", locationId);
  request.setRequestHeader("Terminal", terminalId);
};

var successHandler = function(responseText) {
  var responseObject = JSON.parse(responseText);
  var requestRef = responseObject["requestRef"];
  if(responseObject["success"]) {
    // Request was successful
  } else {
    // Unexpected request problem, hostname might be incorrect.
  }
};

var errorHandler = function(response) {
  var responseObject = JSON.parse(response.responseText);
  var requestRef = responseObject["requestRef"];
  // Something went wrong
};

$.ajax({
  "type": "POST",
  "beforeSend": beforeSend,
  "url": url,
  "data": "{\"filters\":{}}",
  "processData": false,
  "success": successHandler,
  "error": errorHandler
});
// Dependency from Maven: com.google.code.gson >> gson >> 2.3
// Dependency from Maven: org.apache.httpcomponents >> httpclient >> 4.3.5
// Dependency from Maven: commons-io >> commons-io >> 2.4

import java.util.HashMap;
import java.util.Map;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

/**
 * Place a request to the Clutch JSON API.
 * @param method The method name, e.g. search
 * @param requestData Request data to be sent in as a Map structure, will automatically be turned into JSON.
 * @returns Map structure with the parsed response from the server
 * @throws Exception Will throw an exception in case of network errors, invalid JSON coming back or project setup issues
 */
private static Map<String, Object> runRequest(String method, Map<String, Object> requestData) throws Exception {
  String apiKey = "";
  String apiSecret = "";
  String brandId = "";
  String locationId = "";
  String terminalId = "";

  HttpClient client = HttpClientBuilder.create().build();
  HttpPost postRequest = new HttpPost("https://api.clutch.com/merchant/" + method);

  postRequest.setEntity(new StringEntity(new Gson().toJson(requestData)));
  String authHeader = apiKey + ":" + apiSecret;
  postRequest.addHeader("Authorization", "Basic " + new String(Base64.encodeBase64(authHeader.getBytes())));
  postRequest.addHeader("Brand", brandId);
  postRequest.addHeader("Location", locationId);
  postRequest.addHeader("Terminal", terminalId);

  HttpResponse response = client.execute(postRequest);
  int statusCode = response.getStatusLine().getStatusCode();
  String responseBody = IOUtils.toString(response.getEntity().getContent());
  Map<String, Object> responseObj = new Gson().fromJson(responseBody, new TypeToken<Map<String, Object>>(){}.getType());

  Boolean success = (Boolean) responseObj.get("success");
  String requestRef = (String) responseObj.get("requestRef");
  if(success != null && success) {
    // Request was successful
  } else {
    // Request was not successful
  }

  return responseObj;
}
<?php
/**
 * JSONSample.php
 *
 * execute: php JSONSample.php
 *
 */

// Set credentials and variables
$url = "https://api-stage.clutch.com";
$port = "443";
$service = "/merchant/search";

$key = "";
$secret = "";

$cardNumber = "1234";
$brand = "";
$location = "";
$terminal = "";

// Create JSON array
$data = array(
    "filters" => array(
        "cardNumber" => $cardNumber
        ),
    "returnFields" => array(
        "balances" => true,
        "customer" => true,
        "isEnrolled" => true
        )
    );

// Create JSON string
$data_string = json_encode($data);

// Encode basic auth string
$basicAuth = base64_encode($key . ":" . $secret);

// Setup header array
$header = array(
    "Content-Type: application/json",
    "Content-Length: " . strlen($data_string),
    "Authorization: Basic " . $basicAuth,
    "brand: " . $brand,
    "location: " . $location,
    "terminal: " . $terminal
    );

// Setup cURL
$ch = curl_init();

curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");    // Set Method
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string); // Set body request
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);      // Set header
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); // Enable auth type
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);     // Enable SSL verification
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);     // Enable return response
curl_setopt($ch, CURLOPT_URL, $url . $service);     // Set the url
curl_setopt($ch, CURLOPT_PORT, $port);              // Set the port

// Execute
$result = curl_exec($ch);

// Close cURL
curl_close($ch);

// Display results
echo "Raw JSON:\n{$result}\n\n";
echo "Parsed JSON:\n";
var_dump(json_decode($result, true));

?>
import scala.io._;
import dispatch._;
import scala.concurrent.Await
import play.api.libs.ws.WS
import play.api.libs.concurrent.Execution.Implicits._
import scala.concurrent.duration._
import scala.language.postfixOps
import play.api.libs.json.Json


object clutchJSONSearch {

  def search : String = {
    // Set credentials and variables
    var urlStr = "https://api-stage.clutch.com"
    var portStr = "443"
    var serviceStr = "/merchant/search"

    var keyStr = ""
    var secretStr = ""

    var cardNumberStr = ""
    var brandStr = ""
    var locationStr = ""
    var terminalStr = ""

    // Create JSON object
    val jsonObj = Json.obj(
        "filters" -> Json.obj(
            "cardNumber" -> cardNumberStr
        ),
        "returnFields" -> Json.obj(
            "balances" -> true,
            "customer" -> true,
            "isEnrolled" -> true
        )
    )

    // Create JSON string
    val jsonStr = Json.stringify(jsonObj)

    // Build URL
    val fullUrl = urlStr + ":" + portStr + serviceStr 

    // Execute JSON call
    val response  = WS.url(fullUrl)
        .withAuth(keyStr, secretStr, com.ning.http.client.Realm.AuthScheme.BASIC)
        .withHeaders(("Content-type", "application/json"))
        .withHeaders(("brand", brandStr))
        .withHeaders(("location", locationStr))
        .withHeaders(("terminal", terminalStr))
        .post(jsonStr)

    val resultFuture = response map { response =>
      response.status match {
        case 200 => Some(response.body)
        case _ => None
      }
    }

    // Wait for response
    val result = Await.result(resultFuture, 5 seconds).getOrElse("Nothing Returned")

    // Return result
    return result
  }


}
/**
 * JSONSample.cs
 *
 * Compile: csc JSONSample.cs
 * Execute: JSONSample
 * 
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Net;
using System.IO;
using System.Text;

public class JSONSample
{
    public static void Main()
    {
        // Set credentials and variables
        string urlStr = "https://api-stage.clutch.com";
        string portStr = "443";
        string serviceStr = "/merchant/search";

        string keyStr = "";
        string secretStr = "";

        string cardNumberStr = "1234";
        string locationStr = "";
        string terminalStr = "";
        string brandStr = "";

        string responseStr;

        // Create JSON string
        string jsonStr = 
            "{filters:"
                + "{cardNumber:\"" + cardNumberStr + "\"},"
            + "returnFields:"
                + "{balances:true,"
                + "customer:true,"
                + "isEnrolled:true}"
            + "}";

        // Create full URL
        string fullUrl = urlStr + ":" + portStr + serviceStr;

        // Encode basic auth string
        string auth = Convert.ToBase64String(Encoding.ASCII.GetBytes(keyStr + ":" + secretStr));

        // Setup web service call
        var httpWebRequest = (HttpWebRequest)WebRequest.Create(fullUrl);
        httpWebRequest.ContentType = "application/json";
        httpWebRequest.Accept = "*/*";
        httpWebRequest.Method = "POST";
        httpWebRequest.Headers.Add("Authorization", "Basic " + auth);
        httpWebRequest.Headers.Add("location", locationStr);
        httpWebRequest.Headers.Add("terminal", terminalStr);
        httpWebRequest.Headers.Add("brand", brandStr);
        httpWebRequest.ContentLength = jsonStr.Length;

        // Send JSON string request
        Stream dataStream = httpWebRequest.GetRequestStream();
        dataStream.Write(Encoding.ASCII.GetBytes(jsonStr), 0, jsonStr.Length);

        // Get response
        var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();

        // Read response string
        using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
        {
            responseStr = streamReader.ReadToEnd();
        }

        // Display response
        System.Console.WriteLine("\r\nRaw JSON Response:\r\n" + auth +"\r\n");
        System.Console.WriteLine(responseStr);
    }
}

To actually place a request, execute an HTTP POST request using the authentication / identification headers and a stringified JSON request object as post data, i.e. the request body. You can use one of the examples from the right to quickly get started. A good first test is to run a basic search call. Use the API method search and use the request body {"filters":{}}. If this returns a stringified JSON object containing "success": true, your authentication and identification works correctly.

Every request that you execute should respond with a JSON object, even if the request itself failed to execute. In the response will always be a "requestRef" field, which acts as a unique reference to the request.

For successful requests, you will always get back the status code 200. All other status codes indicate a problem has occurred, see Error Handling for more information.

Future Backwards Compatibility

When implementing an API client for the JSON API, one thing to keep in mind is future backwards compatibility. The JSON API adheres to the following versioning design principles:

As a result, new API features will consist of:

Idempotence

Example error response when recycling a customRequestId:

{
  "success": false,
  "errorCode": 3,
  "errorMessage": "This customRequestId has been used before.",
  "requestRef": "10f4c34c-e4e5-4a11-b36f-5ca88289269c"
}

You can optionally add a customRequestId header to your HTTP request. For your brand, the customRequestId has to be unique, or else the JSON API will not execute the request but respond with error code 3 (Duplicate custom request ID).

You can safely execute the same request multiple times if it is using the same customRequestId, and it will only execute once. This can be useful in case of a network communication problem that leaves you unaware of the execution state of a request.

A good way to generate customRequestIds for your requests is by using UUIDv4s, as they are extremely unlikely to ever be the same, regardless of the machine they are generated on.

There is no limit to the size of your customRequestId, but for practical reasons it would be sensible to keep it roughly between 10 and 100 bytes.

Error Handling

Example error response:

{
  "success": false,
  "errorCode": 2,
  "errorMessage": "Your card could not be found.",
  "requestRef": "1455169c-a3c9-4896-9b45-3b72606e55dd"
}

Under normal circumstances you will never get any different response back from the JSON API server than a JSON structure containing at least a "success" field. If this success value is false, this indicate the JSON API ran into trouble while trying to execute your request.

In case the success field is false, there will always be 2 additional fields present in the response, errorCode and errorMessage. In your API code, you should only consider the errorCode, and ignore the errorMessage value. For a list of all error codes and their meaning, see the Error Codes section in this document. The errorMessage field will usually contain a descriptive message that can help a developer establish why a request did not process properly.

If the error code that is returned is 1 (Internal server error), please contact Clutch at asksupport@clutch.com to determine the root cause of the problem, including the requestRef field that you got back.

If you do not get a JSON object back in the response body, something unexpected has happened. Please verify the URL for the endpoint you are using is correct. If this is correct and you are still not getting back a JSON object in the response body, please contact asksupport@clutch.com and include the URL and exact date and time of the request.

Retry policy

If a request has failed to execute due to a network connectivity problem, you should retry the request. When retrying a request, it is important to ensure the same request never gets executed more than once, so for instance an issuance of $10 on a giftcard does not result in a total issuance of $20.

Make sure you are using a customRequestId (see Idempotence section for more information) if you are considering retrying a request. Optimally, retry a request using an exponential backoff algorithm:

  1. Place the request
  2. If the request is not successful, look at the cause, for instance look at the "errorCode" field if there is one coming back). If this is an error that can be retried, wait 2 seconds and try again
  3. If the request failed yet again, look at the cause of the error or errorCode again. If the errorCode is 3 (Duplicate custom request ID), the first request was successful anyway, stop retrying. Otherwise, if this is an error that can be retried, wait X seconds and try again. X is double the amount of seconds from the previous try.
  4. Repeat the process, at most 5-10 times per request.

Errors you could retry:

Employee identification

If you also want to specify which employee is executing a request, you can add the headers:

Troubleshooting

If you have any problems with a request that you cannot figure out, please contact asksupport@clutch.com and include the "requestRef" value from the response(s) to the request(s) you are inquiring about.

If you do not have a "requestRef", please record the exact date and time of your request and the URL you were trying to hit. This can sometimes also help narrow down your request and find the problem.

Campaigns

Campaigns are used to execute certain business logic automatically when a (loyalty) card is being used or to automate promotions. You can configure your own campaigns through the Clutch Portal.

Most campaigns will be checkout-triggered, meaning they only apply to Checkout API calls. You could use campaigns to give 1 loyalty point per USD spent, give a 10% discount to loyalty customers, give 50% off every third hat purchased in your store, or really almost anything you can come up with.

Campaigns can also be set up to enhance your omni-channel interaction with a customer. You could for instance automatically send a thank you message to a customer’s email every time they make a big purchase in your store.

Structure

Within your brand you can have 0 to many campaigns. A campaign is a logical grouping of one or more campaign rules, which you can name for your convenience.

A campaign rule consists of:

If a campaign rule’s conditions are all met (or if there are no conditions), all of the results associated with that campaign rule will be executed.

Per campaign rule, you can specify what triggers its execution. Most of the time this will be checkout-triggered, meaning that every Checkout API call will trigger this rule. You can also have campaign rules that trigger on a customer’s birthday for instance. For more information about all the different triggers, see the Triggers section.

Within your brand, all campaign rules from all your campaigns will by default be considered for execution after every API request. If you want a campaign rule to only apply when cards from a specific program or card set are being used, you can add a condition to the campaign rule to make sure the card being used in the API request comes from that card set or program.

The results of a campaign rule are usually giving away balance or a discount, or sending out a notification.

Notifications

One of the possible results that you can add to campaign rules is a notification. A notification is an asynchronously executed message that gets passed to an external system, with the exception of ‘direct’ notifications. Direct notifications only apply to checkout-triggered campaign rules, they are messages that get sent back along with a Checkout API response.

The message body of a notification follows a standard template. In this template, you can use a number of variables that get converted into customer-specific values when the notification is generated. It can for instance include the current USD balance in an email that is sent to the customer, thankig them for their purchase and informing them of their new balance.

You can use the campaign manager to set up notification and add relevant variables. The variables will usually be in a format similar to this: {{balance balanceType="Currency" balanceCode="USD"}}.

Third party configuration

Before being able to send emails using campaign notifications, or any other form of external communication, you will have to configure the third party send medium settings. For emails, you can for instance configure your Sendgrid settings. Sendgrid is a third party that can act as an email gateway, see: [http://sendgrid.com]. You can configure your brand’s third party settings through the Portal as well. In the left menu, use Admin -> Credentials and pick the third party for which you want to configure your settings.

Triggers

Campaign rules can be triggered by different events. When a campaign rule is triggered, it does not mean that it will actually execute its results, it simply means that it will check the conditions and those match, the results will be executed.

Triggers:

When you set up a date-triggered campaign rule, there are usually 3 things to configure:

  1. Which event the campaign rule should be triggered on, e.g. customer’s birthday. This will start a general 'date-triggered’ execution of all campaign rules that are date-triggered, not specifically limited to this one campaign rule.
  2. A condition that makes sure the event you want to trigger on is happening today. If another campaign rule caused a 'date-triggered’ campaign execution for a card, you might not want this campaign rule to execute. E.g. if you are triggering on a customer’s birthday, also add a condition to check for the event 'customer birthday’.
  3. A throttle, i.e. the max occurrences and run settings for the campaign rule. Make sure that your campaign rule only runs once per 11 months for instance, to make sure someone could not abuse your campaign by for instance changing their birthday too often.

API Methods

Method (path) Description Request Response
allocateChildCard Allocate a child card AllocateChildCardRequest AllocateChildCardResponse
allocateCoupon Allocate or active a coupon AllocateCouponRequest AllocateCouponResponse
allocate Allocate or activate a card AllocateRequest AllocateResponse
cardHistory Look up recent transaction history for a card CardHistoryRequest CardHistoryResponse
channelSubscription Retrieve a channel subscription entry for email, phone, etc ChannelSubscriptionRequest ChannelSubscriptionResponse
checkout Placing a checkout CheckoutRequest CheckoutResponse
couponDetails Look at the details for a coupon, or update the state of a coupon CouponDetailsRequest CouponDetailsResponse
createEventType Create an event type CreateEventTypeRequest CreateEventTypeResponse
listEventTypes List all event types ListEventTypesRequest ListEventTypesResponse
listRequests List requests by external reference ListRequestsRequest ListRequestsResponse
listValueTypes List all value types for a card set or card ListValueTypesRequest ListValueTypesResponse
listSubscriptionLists List all subscription lists for a brand by type ListSubscriptionListsRequest ListSubscriptionListsResponse
reactivate Reactivate a card ReactivateRequest ReactivateResponse
requestLookup Find information about a request RequestLookupRequest RequestLookupResponse
returnMerchandise Returning merchandise ReturnRequest ReturnResponse
search Searching for cards or looking up a card SearchRequest SearchResponse
transfer Transfer card data from one card to another TransferRequest TransferResponse
triggerCustomCampaigns Trigger campaign rules with trigger=custom TriggerCustomCampaignRequest TriggerCustomCampaignResponse
updateAccount Update demographics or other fields associated with one card UpdateAccountRequest UpdateAccountResponse
updateBalance Increasing, decreasing or reserving balance manually UpdateBalanceRequest UpdateBalanceResponse
updateChannelSubscription Maintain channel subscription entry for email, phone, etc UpdateChannelSubscriptionRequest UpdateChannelSubscriptionResponse
voidTransaction Void a transaction, undoing balance mutations VoidRequest VoidResponse

Allocating Cards

To allocate a card or activate a specific card that has not been activated previously, use the allocate API method. This method takes an AllocateRequest model as input and returns an AllocateResponse model.

When allocating a card, you will receive the cardNumber and card’s pin in the response.

You can allocate a card from a card set, in which case we will pick a random available card, but you can also activate a specific card number, in which case you must already know the card number of a card in a card set’s ‘inventory’. Which type of allocation call is most optimal depends on your situation. If you have a physical card, you will usually want to physically pick one and specify the card number. For virtual cards, allocation from a card set is usually preferred.

Allocating from a card set

Example allocation request from a card set:

{
  "cardSetId": "goodCardSet42"
}

Example response:

{
  "success": true,
  "requestRef": "af8f8adc-bca7-4b54-9518-b741c0520e40",
  "cardNumber": "1234",
  "pin": "4321"
}

To allocate a card from a card set, just specify the "cardSetId" field, indicating from which card set you want to allocate a card. If the card set does not have any available cards left in it, "errorCode": 16 (Card set depleted) will be returned. If this happens, contact asksupport@clutch.com. By default, this should never happen, as the Clutch support team actively monitors card sets to ensure they don’t just run out.

Common use cases

Activating a specific card

Example request to activate a specific card:

{
  "cardNumber": "1234"
}

You can also allocate a card if you already know exactly which card number you want to use. In this case, just specify the "cardNumber" field in the request. If the request is successful, the card number and pin will be returned in the response, similar to an allocation from a card set.

Common use cases

Allocating Coupons

Example random coupon allocation request:

{
  "couponSetId": "your-coupon-set-id-here"
}

Example response:

{
  "success": true,
  "requestRef": "b5889a0f-3426-4381-84eb-6c2b7d79bdb9",
  "couponId": "1234567890",
  "customTags": ["Tag123", "10PERCENTOFF"],
  "allowedWithCards": ["card-number-1"]
}

Alternative response, if the coupon had no data on it (yet):

{
  "success": true,
  "requestRef": "b5889a0f-3426-4381-84eb-6c2b7d79bdba",
  "couponId": "1234567890"
}

To allocate a coupon or the mark a specific coupon as allocated / activated, use an AllocateCouponRequest object, the response will be an AllocateCouponRespone object.

The request to allocate a coupon will either have to specify a coupon set to allocate a coupon from, or a specific coupon ID to flag as allocated, you can’t specify both in the same request.

Once a coupon has been allocated it can never be unallocated. It can be marked as used or unused, and the custom tags / allowed with cards lists can be updated, but it can’t be removed or unallocated again.

Card History Lookup

Example card history request:

{
  "cardNumber": "1234",
  "beginDate": "2000-01-01 13:00:00",
  "endDate": "2001-12-31 23:59:59"
}

Example response:

{
  "success": true,
  "requestRef": "de665b85-0392-4c70-a882-0adf44a4aa27",
  "transactions": [
    {
      "transactionId": "5500112233",
      "isLegacy": false,
      "transactionTime": 1422460094976,
      "location": "webStore123"
    },
    ...
  ]
}

The cardHistory API method can be used to get a quick overview of the recent requests for a certain card. The request is defined using a CardHistoryRequest model and the response will be a CardHistoryResponse model.

The only required input for a cardHistory request is the "cardNumber" field. Optionally, you can also restrict the date range of the transactions of which you want to receive information.

The response of this API call will be a list of all matching transactions, specified in the "transactions" field of the response. This field will contain an array of HistoricTransaction models, one per transaction. The returned transactions will be in descending order of processed time, so the most recent transaction will show up first.

Each HistoricTransaction model will contain the field "isLegacy", which is true for transactions that were submitted using an API other than the JSON API.

Checkouts

A checkout is defined as a customer transaction where products are bought, whether a (loyalty) card was used or not. By recording checkouts for both (loyalty) card users and anonymous customers, the reports we can generate for you will become more enhanced.

For all related fields, see the CheckoutRequest and CheckoutResponse models.

To get information about a customer’s card first, it can be useful to go through the following search flow:

In step 1, either scan / swipe a physical card to get its number, ask for the customer’s phone number or full name. The information from step 4 can contain balance data, which can be useful to offer as a potential payment method. See also Tracking payment methods and lift.

Once you have a card, or are completing a checkout for an anonymous customer, there are 3 different types of checkouts to choose from:

An example of the process with a two-stage checkout:

To make this locking, step 2 is flagged as a lock request and step 6 references the response from step 3.

It is possible to repeat the setup call multiple times, to alter the data that is sent in in step 1 and present new information to the customer in step 4. Nothing is finalized until step 5 / 6.

Which checkout type do you need?

Are you using a (loyalty) card for the checkout?

No? Use: Standalone checkouts.

Otherwise, do you have Campaigns set up that give discounts?

No? Use: Standalone checkouts.

Otherwise, are the discounts only caused by the products being purchased or the current checkout total?

Yes? Use: Non-locking two-stage checkouts.

No? Use: Locking two-stage checkouts, but consider Locking Alternatives.

Standalone checkout

Most basic standalone checkout, with the optional cardNumber field set:

curl https://api-stage.clutch.com/merchant/checkout -X POST \
  -u "API_KEY:API_SECRET" \
  -H "brand: BRAND_ID" \
  -H "location: LOCATION_ID" \
  -H "terminal: TERMINAL_ID" \
  -d \
'{
  "cardNumber": "1234",
  "checkoutTotal": 100.50
}'
{
  "cardNumber": "1234",
  "checkoutTotal": 100.50
}

Standalone checkout example with SKUs being used to calculate the checkoutTotal (optional):

curl https://api-stage.clutch.com/merchant/checkout -X POST \
  -u "API_KEY:API_SECRET" \
  -H "brand: BRAND_ID" \
  -H "location: LOCATION_ID" \
  -H "terminal: TERMINAL_ID" \
  -d \
'{
  "cardNumber": "1234",
  "products": [
    {
      "sku": "ABCD",
      "amountPurchased": 5,
      "unitPrice": 20.10
    }
  ]
}'
{
  "cardNumber": "1234",
  "products": [
    {
      "sku": "ABCD",
      "amountPurchased": 5,
      "unitPrice": 20.10
    }
  ]
}

Example checkout response (very basic):

curl https://api-stage.clutch.com/merchant/checkout -X POST \
  -u "API_KEY:API_SECRET" \
  -H "brand: BRAND_ID" \
  -H "location: LOCATION_ID" \
  -H "terminal: TERMINAL_ID" \
  -d \
'{
    "requestRef": "4ba2875f-17c4-4005-b95e-638a48984bfe",
    "responseMessages": [],
    "transactionId": "4500112233",
    "checkoutTotalBeforeDiscount": 100.50,
    "totalDiscount": 0,
    "success": true,
    "cardNumber": "1234"
}'
{
    "requestRef": "4ba2875f-17c4-4005-b95e-638a48984bfe",
    "responseMessages": [],
    "transactionId": "4500112233",
    "checkoutTotalBeforeDiscount": 100.50,
    "totalDiscount": 0,
    "success": true,
    "cardNumber": "1234"
}

The standalone checkout is the simplest checkout call available. Just place one API call per checkout and at the end of the call all related balance and counter mutations will be final.

Optionally, a card number can be specified along with the request, to indicate that a (loyalty) card was used. The card number used in a checkout request should be the card on which you would want any loyalty points to be issued. Points are awarded based on the Campaigns set up for your brand. You can use cards from any one of your card sets in checkouts. If a checkout uses a card from a card set from a program that does not have Points set up as a value type, campaigns issuing Points will simply not issue anything. You can also restrict campaign rules to only work for certain card sets if you prefer.

As part of the checkout request, you can also send in SKU-level data. This is effectively a description of the contents of the customer’s cart for this checkout. It can contain the SKU of each product, the unit price and the quantity that was purchased.

The checkout total should always be sent in as part of the request for reporting purposes. If you are also sending in a full list of all SKUs, quantities and unit prices, you can choose to leave out the checkoutTotal parameter and we will calculate the checkout total based on the SKU-level data.

When to use

When not to use

Two-stage checkout - Non-Locking

A simple checkout setup request, only difference with a standalone checkout is the isSetup value:

curl https://api-stage.clutch.com/merchant/checkout -X POST \
  -u "API_KEY:API_SECRET" \
  -H "brand: BRAND_ID" \
  -H "location: LOCATION_ID" \
  -H "terminal: TERMINAL_ID" \
  -d \
'{
  "cardNumber": "1234",
  "checkoutTotal": 100.50,
  "isSetup": true
}'
{
  "cardNumber": "1234",
  "checkoutTotal": 100.50,
  "isSetup": true
}

The second stage in this approach is exactly the same as a standalone checkout.

A non-locking two-stage checkout consists of one ‘checkout setup’ API call to establish the discount and/or any balance changes that would happen, to get you enough information to start the payment process. Once payment is complete, place a standalone checkout API call to finalize the checkout.

When using this approach, it is very important that the discounts for a checkout cannot change between the first and second API call. It is called a 'non-locking’ checkout, as the checkout setup API call will not lock in the discount, but is simply expecting the discount to remain consistent by the design of your Campaigns.

When to use

When not to use

Two-stage checkout - Locking

A simple locking checkout setup request for a 600s (10 min) lock:

curl https://api-stage.clutch.com/merchant/checkout -X POST \
  -u "API_KEY:API_SECRET" \
  -H "brand: BRAND_ID" \
  -H "location: LOCATION_ID" \
  -H "terminal: TERMINAL_ID" \
  -d \
'{
  "cardNumber": "1234",
  "checkoutTotal": 100.50,
  "isSetup": true,
  "lockSetupDuration": 600
}'
{
  "cardNumber": "1234",
  "checkoutTotal": 100.50,
  "isSetup": true,
  "lockSetupDuration": 600
}

The response is the same as with a standalone checkout.

An example checkout complete request for a locked setup (never contains SKU data or a checkout total):

curl https://api-stage.clutch.com/merchant/checkout -X POST \
  -u "API_KEY:API_SECRET" \
  -H "brand: BRAND_ID" \
  -H "location: LOCATION_ID" \
  -H "terminal: TERMINAL_ID" \
  -d \
'{
  "cardNumber": "1234",
  "isSetup": false,
  "relatedSetupTransactionId": "4500112233"
}'
{
  "cardNumber": "1234",
  "isSetup": false,
  "relatedSetupTransactionId": "4500112233"
}

A checkout cancel request to cancel a checkout lock early:

curl https://api-stage.clutch.com/merchant/checkout -X POST \
  -u "API_KEY:API_SECRET" \
  -H "brand: BRAND_ID" \
  -H "location: LOCATION_ID" \
  -H "terminal: TERMINAL_ID" \
  -d \
'{
  "cardNumber": "1234",
  "cancelSetup": true,
  "relatedSetupTransactionId": "4500112233"
}'
{
  "cardNumber": "1234",
  "cancelSetup": true,
  "relatedSetupTransactionId": "4500112233"
}

A simple checkout setup request that excludes USD balance from its lock:

curl https://api-stage.clutch.com/merchant/checkout -X POST \
  -u "API_KEY:API_SECRET" \
  -H "brand: BRAND_ID" \
  -H "location: LOCATION_ID" \
  -H "terminal: TERMINAL_ID" \
  -d \
'{
  "cardNumber": "1234",
  "checkoutTotal": 100.50,
  "isSetup": true,
  "lockSetupDuration": 600,
  "lockExcludedValueTypes": [
    {
      "balanceType": "Currency",
      "balanceCode": "USD"
    }
  ]
}'
{
  "cardNumber": "1234",
  "checkoutTotal": 100.50,
  "isSetup": true,
  "lockSetupDuration": 600,
  "lockExcludedValueTypes": [
    {
      "balanceType": "Currency",
      "balanceCode": "USD"
    }
  ]
}

A locking two-stage checkout starts out with a locking checkout setup API call. Once this call is placed, the card becomes locked for the specified amount of time. Within this time you can choose to complete or cancel the checkout. Once the lock expires, it will automatically be cancelled and you will be unable to complete the checkout anymore without setting it up again.

Once the checkout has been set up, you will know the discounted checkout total, and you can start the payment process. Once payment is complete, you can run the checkout complete API call to finalize the transaction. You should not pass in the SKU data or checkout total in the checkout complete API call for a locking setup - just send in the card number, related setup transaction ID (from the response of the checkout setup API call) and the flag "isSetup": false.

The created 'lock’ on the card provides a guarantee that the checkout complete API call will do exactly what you expect it to, but as a result you will be unable to do anything else with the card between the checkout setup and complete API calls. Doing so could possibly change the campaign actions, so while the lock is active, the API prevents you from starting another checkout, updating balances on the card, enrolling the customer or modifying any card-related settings or fields.

To still use one or more value types in UpdateBalance API calls while the card is locked, you could set lockExcludedValueTypes on the locking checkout setup API call. This can be useful when the checkout is (partially) paid for using USD balance on a card, when no campaigns are set up to work with USD anyway.

Why locking checkouts?

If your campaigns calculate a discount / updated checkout total, you must know this discounted total (A) before the customer can start the payment process. If something on the card were to change during this payment process that (indirectly) changes the discount, the checkout total that is due could be higher or lower than A, meaning an incorrect amount was paid. To prevent this from happening, you can choose to have the checkout setup 'lock’ the card during the payment process.

When to use

When not to use

Errors while accessing a locked card

When trying to start a new checkout for a campaign that is locked, you will get an error message back. The response will have an error code 14 (checkout in progress). In addition, the response will contain a "checkoutSetupTransactionId": "5500112233" field, indicating the transaction ID of the current checkout setup for the used card.

Locking Alternatives

In some situations, it might not be possible or convenient to use a two-stage locking checkout. The base requirement for a two-stage checkout was: you need to know the discount before paying (one stage) and indicate that the checkout was complete afterwards (second stage). Also, the discount needs to remain consistent between the two stage, to ensure the total that was paid matches the total that is due (locking).

As a possible alternative, you could also choose to use 'cashback’ balance and use a non-locking two-stage checkout instead.

Example setup:

Example flow:

Step 1: New customer places a first checkout for $60, not buying hats

The first call (checkout setup) determines that the discount is $0, payment starts and once payment is complete, the second call is placed to flag the checkout as completed. During this second stage, 60 points get issued.

Step 2: Customer comes back and buys $70 worth of goods, including one hat

The first call determines that the discount is $5. Payment for $65 starts and once payment is complete, the second call is palced to complete the checkout. During this second stage, 65 points are added (reaching 60 + 65 = 125 points), then 100 points are removed and 5 cashback balance is issued. This results in 25 points and $5 in cashback balance on the card. Cashback balance is not Currency.USD, but Custom.cashback in this instance.

Step 3: Customer places another $50 checkout, not buying any hats

The first call determines that the discount is $0, and also returns the cashback balance 5. The amount due is determined to be $50 and the customer could be asked whether they want to use the cashback balance (or partially). If they do choose this option and for instance want to use 4 of this cashback balance, place a balance hold call, effectively reserving 4 of the 5 cashback balance.

At the POS, payment for $4 is now considered complete due to the reservation, leaving $46 to be paid (amount is calculated at the POS). Once this amount is paid as well, a checkout complete API call is placed (second stage). In the checkout complete, indicate the payment methods used, including $4 from a loyalty card, see: Tracking payment methods. Tracking payment methods is not required, but would improve the quality of generated reports.

Once the checkout is complete, do a hold redemption API call, see: balance holds. This will actually 'use’ the reservation on the balance and redeem it.

Expanding response data

Add these 2 fields to a checkout setup or standalone checkout request:

curl https://api-stage.clutch.com/merchant/checkout -X POST \
  -u "API_KEY:API_SECRET" \
  -H "brand: BRAND_ID" \
  -H "location: LOCATION_ID" \
  -H "terminal: TERMINAL_ID" \
  -d \
'{
  ...
  "returnBalances": true,
  "returnBalanceMutations": true
}'
{
  ...
  "returnBalances": true,
  "returnBalanceMutations": true
}

The response will be expanded with these fields:

{
  ...
  "balanceMutations": [
    {
      "campaignUUID": "7c206e9c-0896-4957-b7df-1a694e39ff69",
      "campaignRuleUUID": "8b2f1bad-d31f-41c3-8760-5eddd2b6bc23",
      "campaignResultUUID": "c7d615a7-3449-478a-a0d0-2bd1c118a8dd",
      "amount": 1,
      "isDiscount": false,
      "balanceType": "Points"
    }, {
       "campaignUUID": "7c206e9c-0896-4957-b7df-1a694e39ff69",
       "campaignRuleUUID": "8b2f1bad-d31f-41c3-8760-5eddd2b6bc23",
       "campaignResultUUID": "96c0f317-0190-4999-8ed8-22ee553222e4",
       "amount": 5,
       "isDiscount": true,
       "sku": "112233",
       "skuAmount": 2,
       "skuUnitDiscount": 2.50,
       "skuUnitPrice": 10.00
    }
  ],
  "balances": [
    {
      "amount": 3,
      "scale": 2,
      "isHold": false,
      "balanceType": "Points"
    }
  ]
}

In some cases, you might want to know more details about the balance mutations that were triggered by a checkout, or get back the balances as they stand at the end of the finalized checkout request. You can add the fields "returnBalances": true and / or "returnBalanceMutations": true to any checkout API call to obtain this information, with the exception of checkout cancel API requests.

The returned balances will be the balances as they are or will be after the indicated balance mutations are applied. I.e. if you are using a checkout setup API call, the resulting balances will be purely hypothetical.

Every returned balance mutation will explain what caused the mutation. For mutations that were caused by campaigns, there will always be a campaign and campaign rule associated with the mutation and optionally a campaign result or campaign condition. The UUIDs for these objects are not visible in the Clutch Portal, but are available on request.

If a mutation object explains a discount, it can optionally also explain to which SKU of which unit price the mutation.

Example 1 - General discount

If your campaign is set up to give a $10 discount under certain conditions and this discount is given during a checkout, you will have one balanceMutation object coming back. On this object, no SKU references will be set, as the discount applies to the entire checkout and not to one SKU in particular.

Example 2 - 50% off every second hat

If your campaign is set up to give 50% off every second hat that is purchased and a customer purchases 5 hats, you will see 2 balanceMutations coming back. Each balanceMutation object would specify which SKU the discount applied to. In case you have multiple SKUs with different unit prices, you can figure out which SKU the discount applies to by looking at the skuUnitPrice field coming back as well. This field contains the unit price of the SKU before discounts.

In case of SKU-related discounts, each balanceMutation object will also specify the skuAmount, which is the quantity of the SKU that the discount applies to and a skuUnitDiscount which is the discount per unit of the SKU. By definition, skuAmount multiplied by skuUnitDiscount will be equal to the amount field.

Interactive Campaigns - Custom key/values

Adding custom key/values to a checkout request:

{
  ...
  "customKeyValues": [
    {
      "key": "yourKeyName",
      "value": "someValue"
    }, {
      "key": "orTheSameKey",
      "value": "someValue"
    },  {
      "key": "orTheSameKey",
      "value": "someOtherValue"
    }
  ]
}

In some use cases, you might want to have more control over the Campaigns from the API client code. In these cases, you can send in key/value pairs along with the checkout request and add a condition to a campaign rule to make sure it only fires if a certain custom key has one of a few pre-defined values.

You can send in multiple key/value pairs with the same key if you would like, using multiple CheckoutKeyValue objects in an array in the "customKeyValues" parameter of the checkout API call.

Example 1 - Discretionary campaign

You might have a discretionary campaign set up to give a 10% discount, where it is up to the cashier at the PoS to determine whether this campaign is used or not. It could for instance be used to give a small bonus to loyal customers who have been queueing for the cash register for a long time. With every request, you could send in a key/value object with key “runSpecialDiscount” and values “yes” or “no” - sending in a “no” value would be optional. In your campaign rule, you could set up a condition where the campaign only runs if the custom key “runSpecialDiscount” was set to “yes”.

You can optionally also expand the campaign rule to have multiple conditions and for instance only allow this special discount if both the custom key/value match and the card that was used comes from a certain card set.

Example 2 - Customer’s choice

The custom key/values also enable interaction between the campaigns and the customer. For example, a campaign rule can be set up to give a 10% discount on one hat and another campaign rule can be set up to give a 10% discount on one tie. But - the customer has to choose which of the 2 campaigns they want to use on their checkout. At the Point of Sale, the cashier would ask the customer which promotion they want to use. Based on this choice, the Point of Sale could call the checkout API with a custom key “customerChoice” set to either “hat” or “tie”.

In each of the 2 campaign rules, you can then set up a condition to ensure the rule only executes when the right custom key is sent in.

Example 3 - Promotions

Adding custom key/values for promo codes:

{
  ...
  "customKeyValues": [
    {
      "key": "promoCode",
      "value": "HATS123"
    }, {
      "key": "promoCode",
      "value": "7TIES"
    }
  ]
}

You might want to run a promotion where you print a promo code in a magazine, e.g. you have a webshop and put promo code “HATS123” in a magazine. When customers go to your webshop, they can enter one or more promo codes. If they add “HATS123”, they may get a 10% discount on the cheapest hat that is purchased. To prevent abuse, this only works at most once per customer and will not work for anonymous customers.

In this use case, you would pick some key to use for all your promos, for instance "promoCode". In your checkout requests, you can then add one key/value pair per promo code that is applied to the checkout using this key. If a customer wants to add 5 promo codes to a checkout, you would just send in 5 key/value pairs with the same key.

To actually make the promos work, create one campaign rule per promo. The campaign would have one condition of custom key/value, looking for value “HATS123” for key “promoCode” in this case. You can then add a result to give a 10% discount to the cheapest product from the category 'hats’ that was present in the checkout.

To prevent abuse, set the 'max occurrences’ of the campaign rule to at most 1 in total per customer (or for instance per week if you prefer). This will make sure that that particular campaign rule does not get exectued more than once per customer, and will not work for anonymous customers.

You can also add a start/end date to the campaign rule, to ensure that it for instance only works during the first month after this promo code appeared in the magazine. You could of course also just remove the campaign rule for that particular promotion after a month if you would prefer.

Interactive Campaigns - Augmenting API responses

Example checkout response section with direct notifications:

{
  ...
  "responseMessages": [
    "Only 5 points to your next reward!",
    "You're missing out! Add a tie to your purchase to receive a 10% discount on the entire checkout, today only!"
  ]
}

To make Campaigns more interactive, you can allow them to send messages back in the checkout API responses. This can be useful if you want to show a richer output on your Point of Sale for the customer, or to integrate more closely with your own systems.

In any campaign, you can set up notifications as campaign rule results. If the campaign rule’s condition match, all its results will be executed, including any notifications that have been set up as rule results. A notification can use many channels, it could be an email, a tweet or a 'direct’ notification. Direct notifications are messages that are sent out as part of the CheckoutResponse as the array of strings "responseMessages".

For two-stage checkouts, all notifications for your campaigns are not actually sent out until the checkout is finalized, to ensure that for instance emails to your customers are not sent until the checkout is actually finalized. Direct notifications are an exception to this pattern, they will be included in the CheckoutResponse for both checkout setup and checkout complete API calls.

Example 1 - Configure customer-facing messages in your campaign

As shown in the example response on the right, perhaps you want to set up a campaign to incentize a customer to buy a certain product of which you have excess units in stock. This works ideally with either two-stage checkout process, as you can first place a checkout setup API call to get all the customer messages and incentize them to add a product to the order before completing the checkout.

In this case the API flow would be:

  1. Place a checkout setup API call, receive customer messages back.
  2. Show messages to the customer, customer might add another product to the checkout.
  3. Cancel the first checkout and place a new checkout setup call.
  4. Continue as usual

Example 2 - Integrate with non-Clutch results or systems

Another possibility with direct notifications is to send out "responseMessages" entries that are meant to be processed by your API client code. E.g. a campaign could be set up to add an entry to a call list for any customer purchasing over $1000 in merchandise. The Clutch campaign does not have the capability to place phonecalls, so instead you could have a result of responseMessage “automatedAction:call” or any message that is easy for your API client code to process. Your API client code could then send a notification to a customer service employee requesting to call your new high-value customer.

Validating card pin

Adding card pin validation to a checkout request:

{
  ...
  "forcePinValidation": true,
  "pin": "1234"
}

If needed, you can also validate the card’s pin when placing a checkout API request. This is recommended only on the first checkout API call placed, in case of a two-stage checkout process.

The request will simply fail if the provided pin is incorrect. The pin can be obtained during card allocation.

To validate the pin, set "forcePinValidation": true and then specify the pin as a string in the "pin" field of the request.

Integrating with coupons

Adding 'input’ coupons on a checkout call:

{
  ...
  "coupons": ["12345", "55443322"],
  "removeBlockingCoupons": false
}

Output of a checkout call that issued coupons:

{
  ...
  "issuedCouponIDs": ["112233", "554433"]
}

There are two ways in which you can integrate coupons in checkout API calls, you can use them as input, where unused coupons are 'used’, or you can use them as output, where new coupons are allocated and returned. How coupons interact with your checkouts is defined in your campaigns.

Coupon input

For the first option, simply specify a coupons property on the checkout request. This should be an array of all the coupons that should be used on the checkout. If you are using a two-stage checkout, add the coupons to the checkout setup call. If you are using a non-locking two-stage checkout, also make sure to add the coupons to the checkout complete call.

There are two main possibly ways adding coupons to a checkout API call could cause the request to fail:

  1. One of the coupons is used concurrently in another API call, this will result in error code 26 (concurrent coupon access). You could retry the request in this case, or try it without coupons.
  2. One (or more) of the coupons are invalid, because they are not allocated / activated yet, are already used, are disabled or reserved. In this case, the response will also contain blockingCoupons, being an array showing which coupons were not valid. You can also specify "removeBlockingCoupons": true on the checkout request, in which case the checkout will go through and simply remove any coupons that are not valid from the request before processing it.

Coupon output

If any coupons were issued / allocated during the checkout request, they will be included in the checkout response. If you are using a two-stage checkout, the issued coupons will be included only in the checkout complete call. The issued coupons will be present in the form of a "issuedCouponIDs" array of coupon IDs.

Tracking payment methods and lift

Specifying payment methods used in checkout request:

{
  ...
  "paymentMethods": [
    {
      "paymentType": "Giftcard",
      "amount": 10.00
    }, {
      "paymentType": "Cash",
      "amount": 39.99
    }
  ]
}

Checkout request to redeem $10 as payment

{
  "cardNumber": "CARD123",
  "checkoutTotal": 25,
  ...
  "paymentMethods": [
    {
      "redeemBalance": true,
      "balanceType": "Currency",
      "balanceCode": "USD",
      "amount": 10
    }
  ]
}

In the checkout complete API call, you can specify how the customer paid for the checkout. If this is specified, the Clutch reporting engine will be able to establish the 'lift’ on a checkout, being the amount spent in excess of the giftcard balance used.

You can specify the payment method in the checkout setup API call. This is the checkout setup API call for locking two-stage checkouts, and otherwise the standalone checkout API call. For two-stage checkouts, it’s also possible to send in an updated list of payment methods during the checkout complete API call.

If the same (loyalty) card that is being used to place a checkout also holds balances that should pay for (part of) a checkout, it’s possible to redeem balance in the same API call.

In the example call, a card has 10 USD on it to pay for a part of a $25 checkout.

The PaymentMethod objects that can be added to the checkout request are described in detail here.

Referencing upateBalance payment

Checkout request referencing updateBalance call

{
  "cardNumber": "CARD123",
  "checkoutTotal": 25,
  ...
  "paymentMethods": [
    {
      "updateBalanceRequestRef": "d64b9f45-9651-44bc-a6cd-76aaf6108faf"
    }
  ]
}

A payment method can be specified by just the requestRef of an updateBalance call. In this case, the balance type and amount will be extracted from the original updateBalance request.

As a requirement, the referenced updateBalance request should be a redemption or hold redemption - issuances are not allowed.

Non-compatible balance type

Checkout request to pay USD with points

{
  "cardNumber": "CARD123",
  "checkoutTotal": 25,
  ...
  "paymentMethods": [
    {
      "redeemBalance": true,
      "balanceType": "Points",
      "amount": 100,
      "checkoutPaymentAmount": 10
    }
  ]
}

It is also possible to add a payment method to a checkout that pays for a checkout in a different currency or balance type than the main checkout. For instance, during a $25 checkout the consumer could possibly use 100 points to pay for $10 - depending on the configuration.

Campaigns can be configured to automatically take away points and convert those points into a discount, but you could also choose to implement this logic on the API client side. In this case, you should specify both the amount of points to redeem and the amount of the checkout that it pays for.

Counting payment methods as discounts

In some cases, a certain payment should be considered a discount rather than a payment. This can be useful for reporting, for instance to indicate that a $25 checkout that was paid for with a $5 special balance and $20 cash should really be considered as a checkout that was $20 after discounts.

To flag any payment method as a discount, add "countAsDiscount": true to the PaymentMethod object.

Coupon Interactions

Once a coupon has been allocated, it can be modified or used. Even before it has been allocated though, you can already request information about it. To interact with a single specific coupon, use a couponDetails request. This works by sending a CouponDetailsRequest object and sends back a CouponDetailsResponse response object.

Getting coupon details

Example coupon details request:

{
  "couponId": "your-coupon-id",
  "action": "details"
}

Example response:

{
  "success": true,
  "requestRef": "daad8e25-f4fd-4fde-86b6-16a1c2456e42",
  "isAllocated": true,
  "isUsed": false,
  "isDisabled": false
}

Optional bigger response, depending on the coupon:

{
  "success": true,
  "requestRef": "daad8e25-f4fd-4fde-86b6-16a1c2456e42",
  "isAllocated": true,
  "isUsed": false,
  "isDisabled": false,
  "customTags": ["abc", "def"],
  "allowedWithCards": ["1234", "223344"],
  "reservedUntil": "2015-12-31 23:45:00"
}

To get coupon details, you can just place a request where the action is set to details. The response will show whether this coupon has been allocated already, has been used and whether it’s disabled.

The disabled state of a coupon cannot be changed manually, this is only used in combination with locking two-stage checkouts. In these checkouts, the setup API call will allocate coupons already if deemed necessary by the active campaigns, and flag them as disabled. Only when the checkout completes successfully will the coupon be set to enabled. All coupons that are allocated in any other way are never disabled.

If a coupon is not reserved, the reservedUntil field will not be present in the response.

Updating usage state

Request to change coupon usage state:

{
  "couponId": "your-coupon",
  "action": "use"
}

Flag a coupon as unused:

{
  "couponId": "your-coupon",
  "action": "unuse"
}

To flag a coupon as used or flag a used coupon as unused, place a request to the couponDetails API method with the action use or unuse. No other parameters are required.

Reserving a coupon

Reserving a coupon:

{
  "couponId": "your-coupon",
  "action": "reserve",
  "reserveUntil": "2015-12-31 18:15:00"
}

Releasing a reservation:

{
  "couponId": "your-coupon",
  "action": "releaseReservation"
}

Using a reservation:

{
  "couponId": "your-coupon",
  "action": "useReservation"
}

If you want to reserve a coupon for future usage, but not use it just now, you can flag the coupon as being reserved with the action reserve. When doing so, you need to specify a date/time until which the coupon will remain reserved. Until that moment you can choose to either release the reservation or use it. If you don’t do either before the specified date, the coupon will go back to being unused and unreserved, effectively the same as a releaseReservation action.

When you use a coupon as input on a two-stage locking checkout, the associated coupon(s) will automatically go into reserved state until just after the checkout setup lock is set to expire. The checkout locking mechanism will handle the correct coupon reservation release / usage strategy automatically for you.

Updating coupon settings

Request to just update some coupon settings:

{
  "couponId": "your-coupon-123",
  "action": "details",
  "newCustomTags": ["ABC", "DEF"],
  "newAllowedCards": ["card-1234", "55443322"]
}

You can also choose to manually update the tags associated with a coupon, or change the set of cards that is allowed to use a certain coupon. If the list of cards allowed to use a coupon is an empty list, the coupon can be used with any card.

Events

Cards can contain a set of events. Each event will have an event type definition, a date and optionally a payload.

An event type definition consists of:

Event type definitions can be set up to for instance represent an instance where a customer calls customer support. This could have a Category ID of IncomingCall. It’s then possible to add events to cards with this event type and a custom payload to describe the details of that call.

Creating Events

To create a new event, use:

Reading Events

Search request to get events for a card

{
  "filters": {
    "cardNumber": "123123"
  },
  "returnFields": {
    "events": true
  }
}

Search result with events

{
  "cards": [
    {
      "cardNumber": "123123",
      "cardSetId": "SET1",
      "events": [
        {
          "eventDate": ,
          "eventType": "CUSTOM",
          "categoryId": "IncomingCall",
          "payload": "Customer called to ask about product ABC."
        },
        ...
      ]
    }
  ]
}

Events can be used in reporting queries and segments. In addition, they can be used as campaign conditions.

It is also possible manually retrieve all events that are linked with a card, by having the search API method return this.

Managing Event Types

To manage event types, it’s possible to call the listEventTypes and createEventType API methods. Calling listEventTypes will return a list of all event types that have been set up for your brand.

To create a new event type, call the createEventType API method. This will create a new event type definition, or update the name of the existing event type definition with the same category ID. It’s only possible to create event type definitions with the root type CUSTOM using the createEventType API.

Listing Requests

List all requests with a certain external transaction id

{
  "externalTransactionId": "your-id-here"
}

Example response

{
  "requestRef": "707d54c9-67a6-481f-8a2f-c7a55d6dfa11",
  "success": true,
  "requestRefs": [
    "17d8bdaf-0f64-4eb6-ab89-d2e7040dd9e5",
    ...
  ]
}

When placing an API call, it’s possible to add a header externalTransactionId. This value does not have to be unique, and is only used for logging.

It can be useful to send in a reference to a checkout identifier from the client PoS system for instance. All API calls that are related to the same invoice could share an external transaction ID.

To search all requestRefs that were sent in with a certain externalTransactionId header value, you can use the listRequests API method. In the API response, the field requestRefs will contain a list of all matching requestRefs.

Listing Value Types

Looking up value types available to a card:

{
  "lookupCardNumber": "1234"
}

Looking up value types available to a card set:

{
  "cardSetId": "printedCardSet123"
}

Example response:

{
  "success": true,
  "requestRef": "3e6810a6-d373-48d8-97c6-ffc319f1b6ae",
  "valueTypes": [
    {
      "balanceType": "Points"
    }, {
      "balanceType": "Currency",
      "balanceCode": "USD",
      "scale": 2
    }
  ]
}

If you want to know which value types are available to a card or to all cards from a certain card set, use the listValueTypes API method. It requires a ListValueTypesRequest model as input and return a ListValueTypesResponse model.

The request can either specify a card number or a card set for which to look up all available value types.

The response of this API method will contain the field "valueTypes", which is an array of ValueTypeResult models, each representing one value type that is available to the card or to the cards from the specified card set. Each ValueTypeResult model will contain a "balanceType" field, which can be:

In addition, there is a "scale" field, which indicates precision of the balances, i.e. the maximum allowed amount of decimals for any balance using this value type for the specified card or for all cards in the specified card set.

For Custom value type, there is a "balanceCodeDisplay" field, which returns the Code Display field.

Listing Subscription Lists

Looking up SMS subscription lists available:

{
  "communicationChannelType": "phone"
}

Looking up email subscription lists available:

{
  "communicationChannelType": "email"
}

Example response:

{
  "success": true,
  "requestRef": "3e6810a6-d373-48d8-97c6-ffc319f1b6ae",
  "subscriptionLists": [
    {
      "uuid": "2e6810a6-h373-48e8-97c6-ffc319f1b6af",
      "name": "Frequent Flyers",
      "isPublic": true
    }, {
      "uuid": "7e6810a6-s373-48d8-97c6-ffc319f1b6ad",
      "name": "Gift Reminders",
      "isPublic": true
    }
  ]
}

If you want to know which active subscription lists are available, use the listSubscriptionLists API method. It requires a ListSubscriptionListsRequest model as input and returns a ListSubscriptionListsResponse model.

The request must specify the communication channel type.

The response of this API method will contain the field "subscriptionLists", which is an array of SubscriptionListInfo models, each representing one subscription list.

Transfer

Example transfer out request

{
  "cardNumber": "old-card-1234",
  "action": "out"
}

Subsequent transfer in request

{
  "cardNumber": "new-card-5678",
  "action": "in",
  "oldCardNumber": "old-card-1234"
}

The transfer API can be used to transfer balances or demographics information from one card to another. This method takes a TransferRequest model as input and returns a TransferResponse model.

Any transfer of card data consists of 2 separate API calls, first one to transfer the old card out. This request will take a snapshot of the current state of the card and disable it. You will not be able to use the old card after that transaction.

Once the old card has been transferred out, you can choose to transfer it in to another card. You can only do this at most once per old card, i.e. it’s not possible to transfer the balances from one card to more than one other card.

The card that is receiving the transferred data must be an active card, meaning it must have been allocated already. It can optionally also already contain balances or demographics information.

Balance data will always be copied over. If the new card already contained any balances, the balances of the old card will be added up to the existing balances on the new card. Any possible expiration dates on balances will remain the same.

Transferring demographics

Transfer in request that copies demographics:

{
  "cardNumber": "new-card-5678",
  "action": "in",
  "oldCardNumber": "old-card-1234",
  "overwriteDemographics": true
}

If you want to copy over all demographics and the enrollment state of the old card to the new card, add "overwriteDemographics": true to the transfer in request. The transfer out request does not need any modifications to make this work.

If the new card already contained any demographics fields before the transfer, such as a last name, those fields will be overwritten if the overwriteDemographics option is enabled.

If the new card was already enrolled, the enrollment status will never be affected by a transfer request. If the new card was not yet enrolled and the old card was, enabling overwriteDemographics will enroll the new card on the date of the transfer request.

Locks and balance holds

Transferring out a card with holds:

{
  "cardNumber": "old-card-1234",
  "action": "out",
  "ignoreHoldBalances": true
}

If the old card you are transferring out is currently being used in a locking two-stage checkout, the transfer out request will fail. In this case, you have to either cancel or complete the checkout first before starting the transfer.

If the old card that is being transferred out has any ‘hold balances’, i.e. reserved balances on it, the transfer out request will fail by default. When any amount of balance is reserved, it is not allowed to disappear in any way.

You can choose to set the option "ignoreHoldBalances": true in the transfer out request, if you want the transfer out request to release any remaining balance holds before closing the card. In this case, the transfer in request will add the balance to the new card again without any reservations on it.

Custom card number

Copying over custom card number (transfer in):

{
  "cardNumber": "new-card-5678",
  "action": "in",
  "oldCardNumber": "old-card-1234",
  "copyCustomCardNumber": true
}

You have the option set attach a custom card number to any card and there is no uniqueness restriction on this custom card number. As a result, it is possible to also copy over the old custom card number to the new card. This could be useful if you want to maintain some sort of custom reference to the card object in your administration, even after the transfer.

To copy over the custom card number, add "copyCustomCardNumber": true to the transfer in request. The transfer out request can remain unmodified. If no custom card number was present on the old card, the custom card number of the new card will not be touched, otherwise it will be copied over.

Validating card pin

Adding card pin validation to a transfer request:

{
  ...
  "forcePinValidation": true,
  "pin": "1234"
}

If needed, you can also validate the card’s pin when placing a transfer in or out API request. This can be useful if you want to make sure the customer presenting the card is the legitimate card holder.

The request will simply fail if the provided pin is incorrect. The pin can be obtained during card allocation.

To validate the pin, add "forcePinValidation": true to the transfer request and then specify the pin as a string in the "pin" field of the request.

You can add this to transfer in and/or transfer out requests at will. When added to a transfer in request, it will make sure the pin matches with the new card that is being transferred to. When added to a transfer out request, it will make sure the pin matches with the old card that will get closed.

Updating Card Information

Basic updateAccount request:

{
  "cardNumber": "1234",
  "primaryCustomer": {
    "firstName": "John"
  }
}

Example response:

{
  "success": true,
  "requestRef": "02dec53e-752c-40a7-813d-61e76a87ca5c"
}

To update card information, use the API method updateAccount. It can be used to update basic demographics associated with the card, the custom card number, a custom ‘blob’ of data that you want to associate with the card or third-party opt-in settings and links.

Every card has 2 customer objects associated with it, being a primary customer and an alternate customer. In almost all situations you will only need to use the primary customer. The alternate customer object just allows you to store another customer on the card, which will not be searchable.

Not all card data is searchable. You can search on some basic primary customer demographics, the card number, the custom card number or the card set of a card. For more information, see the Searching Cards section.

Loyalty enrollments

Enrolling a customer:

{
  "cardNumber": "1234",
  "countAsEnrollment": true,
  "primaryCustomer": {
    "firstName": "John",
    "lastName": "Smith",
    "phone": "123 456 7890"
  }
}

Any updateAccount call on any non-enrolled cards can be used to indicate the card should be considered 'enrolled’ from now on. You would typically flag a card as enrolled when a customer signs up for a loyalty program, and you can do this with any card from any card set.

To enroll a customer, just add "countAsEnrollment": true to an UpdateAccountRequest. In most cases, you will add some updates to the primaryCustomer object along with this request, as most business logic requires filling out some information as part of an enrollment.

If you want to have Campaigns that are only available to 'loyalty customers’, you can add a campaign rule condition to ensure certain rewards are only available to enrolled customers.

Custom card number

Setting custom card number:

{
  "cardNumber": "1234",
  "customCardNumber": "yourNewCustomCardNumber"
}

In certain situations you might want to assign a custom secondary ID to each card, which you can do by setting the "customCardNumber" field of an UpdateAccountRequest. Once a card’s customCardNumber has been set, you can use it to search the card as well. See the Searching Cards section for more information.

Email opt-in

Request to opt-in for emails:

{
  "cardNumber": "1234",
  "thirdPartyUpdates": [
    {
      "thirdParty": "email",
      "optIn": true
    }
  ]
}

By default, the customer holding a card will not be opted in for emails. If you have a Campaign set up to send out emails to customers in certain events or when certain thresholds are reached, they will not be sent out unless the email field is set on the primaryCustomer object and the customer has opted in for emails.

The opt-in settings of any 'third party’ are controlled through the "thirdPartyUpdates" field, which can contain an array of ThirdPartyCardProperties models.

SMS opt-in

Request to opt-in for SMS:

{
  "cardNumber": "1234",
  "primaryCustomer":{
    "mobilePhone":"123 456 7890"
  },
  "thirdPartyUpdates": [
    {
      "thirdParty": "phone",
      "optIn": true,
      "categories":[{
        "uuid":"fbb60f63-9bd8-4a32-ac84-91a8aa150831",
        "optInPending":true,
        "optIn":true
      }]
    }
  ]
}

SMS requires a double opt-in. This request will trigger an SMS message sent to the phone, which asks the consumer to consent to receive recurring messages. The consumer needs to reply to the message with 'YES’ to be subscribed.

The "uuid" of the list can be obtained using Listing Subscription Lists method.

Phone numbers

Updating a phone number:

{
  "cardNumber": "1234",
  "primaryCustomer": {
    "phone": "123 456 7890"
  }
}

The phone number field is a bit different from all the other demographics fields in a customer object. When you update a phone number, the incoming value will be parsed as a phone number using the country set on the customer object. If a country is specified in the updateAccount request, this country will be used, otherwise a previously stored country for the card is used. If this is not present either, the store location’s country will be used. If this is missing as well, your brand’s location will be used as a last resort.

Internally, the phone number will be stored in E.164 format. If the country code is 'US’ and the phone number that is sent in is “123-456 7890”, it will be stored as “+11234567890”. When doing a Search request, the E.164-formatted phone number will be returned.

The E.164 format is used because it is a uniform and internationally recognized standard for storing phone numbers. Many third party APIs that provide interaction with phones will accept this format and it aids in data deduplication. For more information see: http://www.itu.int/rec/T-REC-E.164/en.

Third party data

Linking a Twitter username to a card:

{
  "cardNumber": "1234",
  "thirdPartyUpdates": [
    {
      "thirdParty": "twitter",
      "optIn": true,
      "username": "someTwitterUsername"
    }
  ]
}

You can specify third party updates for a card in an UpdateAccountRequest to link a customer’s account with a third party with a card. This can be useful if you want to provide omni-channel interaction with your customer. You could for instance set up a Campaign to send out a tweet or direct message on Twitter to any customer who purchased more than $1000 of merchandise in one checkout.

Currently supported third parties:

Custom card data

Setting custom card data on a card:

{
  "cardNumber": "1234",
  "thirdPartyUpdates": [
    {
      "thirdParty": "custom",
      "customData": "Any custom data, could be a stringified JSON object."
    }
  ]
}

To link any custom data you want with a card, first convert it into a String format. You could for instance stringify a JSON object with custom card properties and store this in the customData field.

The custom card data can optionally be returned as part of card search results.

Brand demographics

Setting values for demographics for a brand:

 "brandDemographics": [
    {
      "fieldName": "tier",
      "value": "1"
    }
  ],

The demographics for a brand must be configured prior to setting the values. Demographics of type Integer, Date, and String are supported. Integer values can also represent true and false entries as well as a range of choices.

Validating card pin

Adding card pin validation to an updateAccount request:

{
  ...
  "forcePinValidation": true,
  "pin": "1234"
}

If needed, you can also validate the card’s pin when placing an updateAccount API request. This can be useful if you want to make sure the customer presenting the card is the legitimate card holder.

The request will simply fail if the provided pin is incorrect. The pin can be obtained during card allocation.

To validate the pin, set "forcePinValidation": true and then specify the pin as a string in the "pin" field of the request.

Updating Balances

If you are using Campaigns, your checkout API calls will automatically modify card balances according to the business logic you have set up.

In some scenarios, you might also want to manually update a card’s balances though, for instance when issuing or redeeming giftcards. You can do this using the updateBalance API method, see the UpdateBalanceRequest and UpdateBalanceResponse models for a full definition of the request and response.

These are the main actions you can perform with card balances:

Issuances

Example balance issuance request:

{
  "cardNumber": "1234",
  "action": "issue",
  "amount": {
    "balanceType": "Currency",
    "balanceCode": "USD",
    "amount": 100
  },
  "isReturnRelated": true
}

Example balance issuance request for expiring balance:

{
  "cardNumber": "1234",
  "action": "issue",
  "amount": {
    "balanceType": "Points",
    "amount": 5
  },
  "issuedBalanceExpiration": "2015-12-31 23:59:59"
}

Example response:

{
  "success": true,
  "requestRef": "4929dfea-9a70-46e3-b997-72c1588396be",
  "transactionId": "5500332211",
  "cardNumber": "1234"
}

When issuing balance, you have to specify a positive amount that is not zero, and a value type. You can optionally flag the issued balance as return-related or not, if this is not specified, the balance will be considered not return-related. You would normally specify an issued as return-related if it is ‘store credit’ that was issued as a result of merchandise being returned.

By default, issued balance does not automatically expire. If you want, you can specify the "issuedBalanceExpiration" field on the UpdateBalanceRequest, to indicate when the balance should expire. This date should be in the format yyyy-MM-dd HH:mm:ss, and it needs to be in the UTC (+00:00) timezone.

If your issuance would exceed the balance limits specified for the value type of the balance you’re trying to modify, the request will fail and you will get back "errorCode": 13 (Balance limits exceeded).

Redemptions

Example balance redemption request:

{
  "cardNumber": "1234",
  "action": "redeem",
  "amount": {
    "balanceType": "Points",
    "amount": 5
  }
}

Example redemption request that does not error when overdrawing:

{
  "cardNumber": "1234",
  "action": "redeem",
  "amount": {
    "balanceType": "Points",
    "amount": 5
  },
  "redeemMaxOnOverdraw": true
}

Addition to response when redemption exceeded the available balance:

{
  ...
  "didOverdraw": true,
  "overdrawAmount": 10
}

To redeem balance from a card, use the same request as for a simple issuance, but use the action "redeem" instead. Contrary to issuances, you cannot specify whether you want to redeem from return-related balance or regular balance. See the Redemption logic section for more information.

If you try to redeem more balance than what is available on the card, you will get back "errorCode": 13 (Balance limits exceeded) by default. If you prefer, you can also tell requests to redeem the maximum amount available in such cases, by adding "redeemMaxOnOverdraw": true to the updateBalance request. In these cases, you will also get back "didOverdraw" in the response, indicating whether the request exceeded the available balance. If it did, you will also get back "overdrawAmount": 10, which is the amount that your request was in excess of the available balance.

If you try to redeem 50 Points with "redeemMaxOnOverdraw": true in the request, but you only have 40 Points of balance available on the card, the response will include "didOverdraw": true and "overdrawAmount": 10. If you tried to redeem exactly 40 Points instead, "didOverdraw": false would be returned and "overdrawAmount" would not be present in the response.

Holds - reservations

Example balance reservation request, creating a new hold:

{
  "cardNumber": "1234",
  "action": "hold",
  "amount": {
    "balanceType": "Points",
    "amount": 5
  }
}

Important part of response:

{
  ...
  "transactionId": "5500112233"
}

Example partial redemption from balance hold, releasing the remainder:

{
  "cardNumber": "1234",
  "action": "redeem",
  "redeemFromHoldTransactionId": "5500112233",
  "releaseHoldRemainder": true,
  "amount": {
    "balanceType": "Points",
    "amount": 2
  }
}

In some scenarios, you want to reserve some balance first, without actually redeeming it. In these cases, you can place a balance hold request. A hold request is similar to a redemption, except you cannot use the "redeemMaxOnOverdraw" field. If not enough balance is available to hold, you will always get back "errorCode": 13 (Balance limits exceeded).

Once you have successfully placed a hold, the "transactionId" from the response is very important, as this identifies the hold. If you do a search while the hold is active, you can see a balance being returned with "holdingTransactionId" set to this transactionId.

To use a hold, simply place a regular redemption, but add "redeemFromHoldTransactionId": "5500112233". You can place as many redemptions from one hold as you want, until it runs out. If you want to release the rest of the reserved balance after a partial hold redemption, add "releaseHoldRemainder": true to the request. If this field is not specified, it defaults to false.

By default you cannot redeem an amount of 0, as that transaction would not have any meaning, but there is an exception when you are cancelling a hold. If you want to cancel an entire hold without using it, place a redemption with an amount of 0 and set "releaseHoldRemainder": true.

Returning resulting balances

Addition to updateBalance request:

{
  ...
  "returnBalances": true
}

Additional response data:

{
  ...
  "balances": [
    {
      "balanceType": "Points",
      "amount": 5,
      "scale": 0
    },
    ...
  ]
}

If you want an updateBalance request to also return the resulting card balances, add "returnBalances": true to the UpdateBalanceRequest. The response will then also contain a "balances" field with an array of CardBalance models. This is similar to the Search request.

The returned balances will be the balances as they are at the end of the updateBalance request.

Validating card pin

Adding pin validation to an updateBalance request:

{
  ...
  "forcePinValidation": true,
  "pin": "4321"
}

For extra security, you can require customers to provide a card pin when trying to update their balance. Depending on your business logic, you might for instance want to add this to redemption requests, to ensure that only the legitimate card holder can use their balance.

To check a card’s pin during an UpdateBalance call, just add "forcePinValidation": true to the request and specify the pin that was entered by the customer with "pin": "4321". If the pin is not correct, the request will not process and you will get back "errorCode": 10 (Invalid pin).

Accounting adjustments

An accounting adjustment that also suspends a card:

{
  "cardNumber": "1234",
  "action": "redeem",
  "amount": {
    "balanceType": "Points",
    "amount": 5
  },
  "isAccountingAdjustment": true,
  "adjustStatus": {
    "newStatus": "Suspended"
  }
}

An accounting adjustment to only suspend a card:

{
  "cardNumber": "1234",
  "action": "adjustOnly",
  "isAccountingAdjustment": true,
  "adjustStatus": {
    "newStatus": "Suspended"
  }
}

In some cases you might want to flag a balance update (issuance or redemption only) as an accouting adjustment, for instance when you noticed an incorrect update and want to correct it manually. The only change that is needed to flag an issuance or a redemption as an accounting adjustment is the addition of "isAccountingAdjustment": true to the request.

If you want to adjust the card status as well as part of the adjustment, add the "adjustStatus" field to the UpdateBalanceRequest, populated with an AdjustmentStatusDetails model. You could use this to for instance undo a mutation and then suspend the card prevent it from being used again.

When you only want to change the status of a card, and not actually redeem or issue any balance to it, use "action": "adjustOnly" in the request and don’t specify an "amount".

Redemption logic

If you only ever issue balance that is not return-related and does not have an expiration set on it, your balance administration is very simple. A redemption of Points simply deducts Points balance and an issuance of USD will add USD balance. Once you get some return-related balance and some regular balance of the same value type, or have different expiration dates for different amounts within the same value type, things get a bit more complex.

Redemptions will always follow this order when establishing which balance is redeemed first, all within the relevant value type:

  1. Any return-related balance is redeemed before non-return-related balance. This means store credit is always used first.
  2. Within the return-related or non-return-related balance, first expiring balance is redeemed first, non-expiring balance is used last. Customers will want to use balances that expire (quickly) first when placing any transaction.

A hold will also reserve balance in the same order and when a hold is used, it will redeem from its associated balances using the same order logic.

Returns

Example return request:

{
  "cardNumber": "1234",
  "returnedProducts": [
    {
      "sku": "HAT123",
      "amountPurchased": 1.0,
      "unitPrice": 15.00
    }
  ],
  "additionalReturnAmount": 5.00
}

Example response:

{
  "success": true,
  "requestRef": "de665b85-0392-4c70-a882-0adf44a4aa27"
}

Return requests, using the method returnMerchandise, can register merchandise being returned. For reporting purposes, this will log as the opposite of a checkout. The request is defined using a ReturnRequest model and the response will be a ReturnResponse model.

None of the request fields are required. It’s possible to specify a total being returned without or in addition to a SKU breakdown, by specifying this in the additionalReturnAmount request field. The total returned value will be calculated by the sum of amountPurchased * unitPrice of each SKU, plus additionalReturnAmount.

If the card number that was used to place the original checkout is known, this should be specified on the request in the cardNumber field. This will ensure the return gets logged on the right card and make your reports more reliable.

If you know the requestRef that was returned for the original checkout that is being returned, you can specify this in the request field checkoutRequestRef. If this is specified, the card number must be sent in as well, and it must be the same card number that was used in that original checkout in that case. If the original checkout was a two-stage locking checkout, send in the requestRef returned for the checkout complete API call.

The returnMerchandise API call can perform a number of tasks:

Failure handling

By default, a return request will fail if:

It’s possible to send in "failIfCouponsUsed": false or "failIfOverReturn": false if these situations should not result in the returnMerchandise API call failing.

Logging SKUs

If possible, sending in SKU level detail on the reports is recommended. Send in the quantity being returned using amountPurchased and if possible, also the after-discounts unit price of the SKU in the unitPrice field.

If 2 products with a certain SKU are being returned, set amountPurchased to 2 in the return request. This will effectively be logged as the sale of -2 products.

Searching Cards

Example search request to search for any card:

{
  "filters": {
  }
}

Example search response:

{
  "success": true,
  "requestRef": "51a49ffd-f65a-4da3-a3ad-281ee8917e09",
  "usedCache": true,
  "cards": [
    {
      "cardNumber": "1234",
      "cardSetId": "comboCardGroup1"
    },
    ...
  ]
}

The search API method can be used to search cards or look up information for one specific card. In every search request, you have to specify a SearchFilters model in the "filters" field. If no filters are specified, all cards will match. Add filters to restrict the search results to only those cards matching the specified criteria.

Filters

A card lookup request, where the card number is known:

{
  "filters": {
    "cardNumber": "1234"
  }
}

A card search request, searching by full name:

{
  "filters": {
    "firstName": "John",
    "lastName": "Smith"
  }
}

For card lookups, where you want to find a specific card, you can use either:

When searching for cards where a certain demographics field matches, for instance searching by first and last name, an internal cache will be used for an optimal API response time. See the Cache section for more information.

The full list of filters that are available is shown in the SearchFilters model.

Return fields

Request to return all available card data:

{
  "filters": {},
  "returnFields": {
    "balances": true,
    "customer": true,
    "alternateCustomer": true,
    "giverCustomer": true,
    "isEnrolled": true,
    "customData": true,
    "customCardNumber": true
  }
}

Response with all fields set:

{
  "success": true,
  "requestRef": "10f6b4b2-3dff-4910-847e-5db3924afe86",
  "usedCache": true,
  "cards": [
    {
      "cardNumber": "1234",
      "cardSetId": "abc",
      "balances": [
        {
          "amount": 100,
          "balanceType": "Currency",
          "balanceCode": "USD",
          "scale": 2
        }, {
          "amount": 25,
          "balanceType": "Points",
          "scale": 0
        }
      ],
      "customer": {
        "firstName": "John"
      },
      "isEnrolled": false,
      "customCardNumber": "XYZ_987"
    },
    ...
  ]
}

By default, the returned Card objects will only show their cardNumber and cardSetId fields. If you want more data for each card to be returned, you can specify a SearchReturnFields model in the "returnFields" field and finetune the type of response data you want to see.

If a field is requested to be returned, but the card does not have this data, the field will not be returned for that card. For instance, if the giverCustomer object is requested to be returned, but a card was not given by anyone, the "giverCustomer" field will not be present in the returned Card object for that particular card.

For more information about the balances that can be returned, see the Returned balances section.

Returned balances

Example response showing a USD balance reservation (hold):

{
  ...
  "cards": [
    {
      "balances": [
        {
          "amount": 100,
          "balanceType": "Currency",
          "balanceCode": "USD",
          "scale": 2,
          "isHold": true,
          "holdingTransactionId": "5500112233"
        }
        ...
      ]
    }
    ...
  ]
}

When a card is initially created, no CardBalance objects will be associated with it. When searching for such a card with the return field "balances": true, the response will show "balances": [].

For each value type, there will be at most one CardBalance object that is not a ‘hold’. In addition, it is possible to have multiple holds for one value type for one card, each representing one particular reservation of a certain amount of balance.

For hold balances, the CardBalance object will include "isHold": true and also "holdingTransactionId": "123". The holdingTransactionId field can be used to manipulate the balance reservation through an updateBalance request.

Every balance can be one of 4 different balanceTypes:

Scale

A balance can also show the scale of its associated value type. The scale indicates the maximum amount of allowed decimals. If scale is set to 0, the balance will not contain any decimals. For currency, the scale is usually set to 2, to allow cents but no smaller amounts.

Result paging

Request to get 20 results, skipping the first 40:

{
  "filters": {},
  "limit": 20,
  "offset": 40
}

By default every search request only returns the first 10 results. By specifying the "limit" field in the SearchRequest, you can change the amount of results coming back. You can also specify the "offset" field to skip a certain amount of results. This is usually a multiple of the "limit" value.

Cache

Response showing no cache was used:

{
  "success": true,
  "requestRef": "a03d4a55-dc25-4ad8-a349-bfc7f21d1fbd",
  "cards": [],
  "usedCache": false
}

When the SearchFilters contain nothing except a cardNumber and / or a customCardNumber, the search request is essentially an immediate lookup of a card. In this case, the card will be looked up directly and the search cache will not be used.

If no filters are specified, or filters other than cardNumber or customCardNumber are specified, the JSON API will use an internal search engine. This search engine enables search results to be returned very quickly, but if you update card data, such as the demographics associated with a card, it can take up to a minute for this data to get picked up. As a result, you may be looking at slightly outdated data when searching by anything other than cardNumber or customCardNumber.

You can always see whether the internal search engine was used or not by looking at the API response. The response field "usedCache": true will indicate the internal search engine was used, if it is set to false all data will be up-to-date.

It is recommended to always use a search request with a cardNumber or customCardNumber unless this is really not possible.

Lookups - inactive cards

Search request to look up a card, even if it is not active:

{
  "filters": {
    "cardNumber": "1234"
  },
  "includeInactive": true
}

Example response:

{
  "success": true,
  "requestRef": "db8319a5-b8ac-4461-bd4e-c606d5f16d1f",
  "usedCache": false,
  "cards": [
    {
      "cardNumber": "1234",
      "cardSetId": "abc",
      "cardStatus": "Activated"
    }
  ]
}

By default only active cards will be returned in search results, to ensure that inactive, stolen or suspended cards stay hidden. However, in some cases you may want to look up a specific card and find out its status, even if it’s not active. To achieve this, set "includeInactive": true in the SearchRequest. This will only work if you are performing a search on a cardNumber and / or customCardNumber.

If "includeInactive": true is set, the returned Card object(s) will have a populated cardStatus field. If the card is active, the returned status will be "Activated". For all possible cardStatus values, see the Card model definition.

Lookups - pin validation

Search request to look up a card and validate a pin

{
  "filters": {
    "cardNumber": "1234"
  },
  "forcePinValidation": true,
  "pin": "4321"
}

For security reasons, a card’s pin is never returned except during the card allocation / activation API call. If you want to run a check to see if a customer is the legitimate owner of a card, you could ask them for the pin and place a search request to lookup the card. If you specify "forcePinValidation": true on a SearchRequest and specify the pin with "pin": "4321", the request will only proceed if the pin is correct.

There are the following possible results when enabling pin validation:

Update Channel Subscription

Example subscription request for email:

{
  "channel": "email",
  "channelUser" : "test@test.com",
  "globalOptIn" : true,
  "transactionalOptIn" : false,
  "categories" : [ {"category" : "marketing", "optIn" : true } ],
  "customKeyValues" : [ {"name" : "value1", "value" : "test value"} ]
}

Example subscription request for phone (Note: Non-US numbers must be in E164 format):

{
  "channel": "phone",
  "channelUser" : "123-123-1234",
  "globalOptIn" : true
}

Example response:

{
  "success" : true,
  "requestRef" : "af8f8adc-bca7-4b54-9518-b741c0520e40"
}

To add or update the subscription status of a phone or email use the Update Channel Subscriptions API Method. This method takes an UpdateChannelSubscriptionRequest model as input and returns an UpdateChannelSubscriptionResponse model.

When updating a subscription you will receive true or false in the response.

The Update Channel subscription API allows for setting the subscription status globally, optionally for transactional emails, and optionally for category channels or specific emails lists. Custom key values may also be provided for later retrieval.

Channel Subscription

Example subscription request for email:

{
  "channel": "email",
  "channelUser" : "test@test.com"
}

Example subscription request for phone (Note: Non-US numbers must be in E164 format):

{
  "channel": "phone",
  "channelUser" : "123-123-1234"
}

Example response:

{
  "success" : true,
  "requestRef" : "af8f8adc-bca7-4b54-9518-b741c0520e40",
  "channel" : "email",
  "channelUser" : "test@test.com",
  "globalOptIn" : true,
  "doubleOptIn" : true,
  "doubleOptInConfirmed" : true,
  "transactionalOptIn" : false,
  "categories" : [ {"category" : "marketing", "optIn" : true } ],
  "customKeyValues" : [ {"name" : "value1", "value" : "test value"} ]
}

To retrive the subscription status of a phone or email use the Get Channel Subscriptions API Method. This method takes an ChannelSubscriptionRequest model as input and returns an ChannelSubscriptionResponse model.

When retreiving a subscription you will receive true in the response even in the scenario where no subscription for the channel user exists.

Reactivating Cards

Once a card has been suspended using UpdateBalance, the card may not be updated using any of the regular API methods. However, you can reactivate cards that have a ‘Suspended’ state using the reactivate method. Note that this will not work with cards that have any of the other statusses, such as 'Lost’ or 'Closed’.

Example card reactivate request:

{
  "cardNumber": "1234",
  "forcePinValidation": true,
  "pin": "4567"
}

Example response:

{
  "success": true,
  "requestRef": "4929dfea-9a70-46e3-b997-72c1588396be",
  "transactionId": "5500332211"
}

Voiding Transactions

Example void request:

{
  "cardNumber": "1234",
  "requestRef": "c454ff28-8c64-4573-ad39-7a512f41272b"
}

Example response:

{
  "success": true,
  "requestRef": "de665b85-0392-4c70-a882-0adf44a4aa27"
}

Void requests can undo balance mutations that were made as part of API transactions. The request is defined using a VoidRequest model and the response will be a VoidResponse model.

The only required input for a voidTransaction request are the "cardNumber" and "requestRef" fields.

The void request will only undo balance mutations that were part of the original request. It is not possible to void a request twice and it is not possible to void a void request.

Note that card allocations will not unallocate with a void request and any campaigns that may have been set up that use internal counters will not decrement.

Currency Conversion

It’s possible to use currency conversion to look up balances from a card in a different balance type or redeem balance in a different currency than what is stored on the card.

This can be useful when a gift card should for instance only hold balance that is issued in a single currency, while the card should be usable in stores in multiple countries.

Searching with currency conversion

Search request that obtains converted Euro balances from cards

{
  "filters": {
    ...
  },
  "returnFields": {
    "balances": true
  },
  "convertToCurrency": "EUR"
}

Search response

{
  "cards": [
    {
      "cardNumber": "123123",
      "cardSetId": "SET1",
      "balances": {
        "amount": 100,
        "convertedAmount": 92.30,
        "balanceType": "Currency",
        "balanceCode": "USD",
        "scale": 2
      }
    }
  ]
}

To search with currency conversion enabled, add the target currency code in the convertToCurrency field in the search request body, and add "balances": true to the returnFields property.

Doing so will return all the normal balances that are present on the card, but next to the regular amount property in the resulting balances, there can now also be a convertedAmount property.

If this property is present on any returned balance object, that means this balance is available for redemption in the currency that was specified in convertToCurrency.

In the example request, the card search runs for cards that has USD balances on them and tries to return EUR balances. One card has a 100 USD balance, which is also shown as 92.30 EUR in the example.

Conversion in redemptions

Redemption conversion request

{
  "action": "redeem",
  "amount": {
    "amount": 10,
    "balanceType": "Currency",
    "balanceCode": "EUR",
    "convertToMainCurrency": true
  }
}

Redemption conversion result

{
  ...,
  "convertedAmount": 10.87
}

In updateBalance calls, it’s possible to specify a redemption in a different currency than the card’s main currency and perform a conversion before executing the redemption.

To make a regular updateBalance request redeem from the main currency of a card instead of the one specified in the request, add "convertToMainCurrency": true in the amount object in the request. In the example request, 10 EUR is being redeemed from the card’s main balance, which in this case could be USD. This example request would then for instance redeem 10.87 USD from the card.

The result from the conversion that takes place in the redemption will be shown in the field convertedAmount in the response. This will be the actual amount that was redeemed from the card’s main currency.

Child Cards

Child card allocation request

{
  "cardNumber": "ROOTCARD123",
  "childCardNumber": "childCardNumber123"
}

Update account request to set demographics on child card:

{
  "cardNumber": "ROOTCARD123",
  "childCardNumber": "childCardNumber123",
  "primaryCustomer": {
    "firstName": "John"
  }
}

Depending on the required business logic, it may be desirable to have one or more ‘child cards’ attached to a 'root’ card. The child card can hold demographics or balances, or be used to record checkouts on.

To start with a child card, call allocateChildCard, which takes the root card number and your desired child card number and creates it. The child card number has to be unique within the root card and it is recommended to also make it unique across all your root cards.

With a child card you can use the following API methods, by just adding a childCardNumber field to the request:

In addition, you can get child card information back in:

Child cards do not have all features that regular cards do:

Campaigns can be set up to trigger for child cards or only root cards, depending on the required business logic.

Searching child cards

Search for root cards having a certain child card:

{
  "filters": {},
  "childFilters": {
    "firstName": "John"
  },
  "returnFields": {
    "childCards": true
  }
}

In addition to regular search, it’s also possible to search for root cards by child card properties, or search using both root card filters and child card filters. In the search request structure, use the regular filters property to specify root card filters and optionally specify some child card filters using the childFilters property. If any child card filters are applied, only child cards that match the child card filters will be returned.

To get back child card information in search responses, add "childCards": true to the returnFields field in search requests.

Reference - All Models

This is an overview of all models available in the JSON API. For their usage within requests, see the API methods section.

AdjustmentStatusDetails

Use this object to specify what a card’s status should be updated to.

Parameter Type Required Default Description
newStatus string Yes - New status of the card. After setting the card to one of these states, adjustments can no longer change the state back to Activated through the API.. Allowed values are only: Lost, Closed, Expired, Suspended, Stolen

AllocateChildCardRequest

Request to allocate a child card, used to place allocateChildCard requests.

Parameter Type Required Default Description
childCardNumber string No - Child card number to allocate. The card number has to be unique within the root card, and it is recommended to also keep it unique across all root cards. Length should be between 3 and 25 characters (inclusive), and cannot contain commas. Value should not be longer than 25 characters.
cardNumber string No - Root card number of the card that needs to get a new child card allocated under it.

AllocateChildCardResponse

Response from allocateChildCard requests.

Parameter Type Required Default Description
requestRef string Yes - Unique request reference, can be used for debugging or tracking individual requests / responses.
success boolean Yes false Success flag, true means the request was successfully processed.
errorMessage string No - Error message, can be included if success is false. This field can provide some human-readable insights into the request failure.
errorCode integer No - Error code, will only be included if success is false. See the JSON API documentation for all possible error codes and their meanings.

AllocateCouponRequest

Used to place AllocateCoupon requests, which can be used to allocate a randomly selected coupon from a coupon set, or to allocate a specific coupon.

Parameter Type Required Default Description
createIfNew boolean No false Create the coupon if it does not yet exist (including Inventory or any other status). If this field is set, the couponId and the couponSetId must be specified. This function is available only to select brands. (requires JSON v2)
customTags Array(string) No - Optional, if this value is present in the request and is not null, the custom tags of the specified coupon will be set to this value right as it is allocated. If this value is an empty array, the custom tags will be reset (in case there were already tags on the coupon before allocation).
couponSetId string No - ID of the coupon set from which to allocate a new coupon. If this field is set, couponId should not be specified.
couponId string No - Coupon ID of the coupon to allocate. If this field is set, the couponSetId should not to be specified.
cardNumber string No - Card number of loyalty card to issue this coupon to. Optional field, leave out to only allocate the coupon. If specified, promotionId and allowMultipleCoupons parameters are required.
promotionId string No - ID of the promotion to attach to the coupon on the card. Required if card number is passed in.
expirationDate string No - Optional, if specified, the newly allocated coupon will immediately start out with this expiration date. Format as: yyyy-MM-dd HH:mm:ss, e.g. 2000-01-01 00:00:00. Cannot be in the past. (format: yyyy-MM-dd HH:mm:ss)
allowMultipleCoupons boolean No false Flag to determine if multiple coupons per promotion are allowed for one card. If set to false request will fail if card already has a coupon.

AllocateCouponResponse

Response from AllocateCoupon requests.

Parameter Type Required Default Description
requestRef string Yes - Unique request reference, can be used for debugging or tracking individual requests / responses.
customTags Array(string) No - Optional, can contain custom tags associated with the allocated coupon, if the allocation was successful and the coupon had custom tags associated with it.
success boolean Yes false Success flag, true means the request was successfully processed.
errorMessage string No - Error message, can be included if success is false. This field can provide some human-readable insights into the request failure.
errorCode integer No - Error code, will only be included if success is false. See the JSON API documentation for all possible error codes and their meanings.
couponId string No - Will be available if the allocation was successful. This field contains the coupon ID that was allocated.
allowedWithCards Array(string) No - Optional, can contain a list of card numbers that are allowed to use this coupon. This field is only specified if the allocation was successful and the coupon had card restrictions on it.

AllocateRequest

Used to place Allocate requests, which can be used to allocate a randomly selected card from a card set and activate it, or to activate a specific card.

Parameter Type Required Default Description
createIfNew boolean No false Create the card if it does not yet exist (including Inventory or any other status). If this field is set, the cardNumber and the cardSetId must be specified. This function is available only to select brands. (requires JSON v2)
cardSetId string No - ID of card set from which to allocate a new card, usually for virtual cards. If createIfNew is true, specify this field and also cardNumber. If createIfNew is false, only specify cardNumber or cardSetId, but not both.
cardNumber string No - Card number of the card to allocate, usually used for physical cards. If createIfNew is true, specify this field and also cardSetId. If createIfNew is false, only specify cardNumber or cardSetId, but not both.

AllocateResponse

Response from Allocate requests.

Parameter Type Required Default Description
requestRef string Yes - Unique request reference, can be used for debugging or tracking individual requests / responses.
pin string No - The PIN number for the card that was issued / activated
success boolean Yes false Success flag, true means the request was successfully processed.
errorMessage string No - Error message, can be included if success is false. This field can provide some human-readable insights into the request failure.
errorCode integer No - Error code, will only be included if success is false. See the JSON API documentation for all possible error codes and their meanings.
cardNumber string No - The card number that was issued / activated.

BrandDemographicsProperties

Represents a request to update the custom brand demographics for a card.

Parameter Type Required Default Description
mode string No overwrite Optional, may be set to ‘append’ to append items to fields with multiple values or 'appendUnique’ to only append items that do not already exist within field. Value is ignored for regular single value demographics. Defaults to 'overwrite’. (requires JSON v2). Allowed values are only: appendUnique, overwrite, append
fieldName string Yes - Name of internal field name to set a value for.
values Array(BrandDemographicsValue) No - Optional, may not be provided at the same time as 'value’. List of values to set the field value to, when mode is set to 'overwrite’, passing a null value will unset the property. (requires JSON v2)
value string No - Optional, may not be provided at the same time as 'values’. Value to set the field value to. If field contains a date, the value must be in the yyyy-MM-dd format

BrandDemographicsValue

Represents a single value to add to a brand demographic property on a card. At least one of the fields must be set.

Parameter Type Required Default Description
dateValue string No - Optional, must be present if no other field is set. Date value to add to the list of values in yyyy-MM-dd format.
stringValue string No - Optional, must be present if no other field is set. String value to add to the list of values.
decimalValue number No - Optional, must be present if no other field is set. Decimal value to add to the list of values.
integerValue integer No - Optional, must be present if no other field is set. Integer value to add to the list of values.

CampaignBalanceMutation

Represents a balance mutation or discount that occurred during the request. If this balance mutation was caused by a campaign, this object will also indicate which campaign was responsible. If this object represents a discount and the discount is related to a specific SKU / product, the SKU to which this discount applies will be specified as well.

Parameter Type Required Default Description
campaignUUID string No - UUID of the campaign responsible for this balance mutation.
amount number Yes - Amount that is relevant to this mutation. Discounts always have a positive amount, issuances also have a positive amount and redemptions have a negative amount.
campaignRevisionUUID string No - UUID of the campaign revision of the campaign that was responsible for this balance mutation.
skuUnitPrice number No - If the related SKU is set, this field indicates the original (before-discount) unit price of the SKU purchase to which the discount applies.
skuAmount number No - If the related SKU is set, this field indicates how many units of this SKU this discount applies to.
skuUnitDiscount number No - If the related SKU is set, this field indicates how much the discount per unit of this SKU is.
campaignResultUUID string No - UUID of the campaign result object responsible for this balance mutation if there was one.
isDiscount boolean Yes false Whether this mutation is a discount or a real balance update.
balanceExpiration integer No - Expiration of the issued balance, the number of milliseconds since January 1, 1970, 00:00:00 GMT. Only relevant for issuances. No balanceExpiration means the issued balance does not have any custom expiration rules set on it.
campaignConditionUUID string No - UUID of the campaign condition object responsible for this balance mutation if there was one. Only relevant for conditions that explicitly take away balance, such as the balance condition.
balanceActiveDate integer No - Active date of the issued balance, the number of milliseconds since January 1, 1970, 00:00:00 GMT. Only relevant for issuances. No balanceActiveDate means the issued balance is available immediately.
balanceType string No - The type of balance that this amount represents.. Allowed values are only: Points, Currency, Punches, Custom
balanceCode string No - If the balance type is Currency or Custom, this field indicates the currency code or custom code of the balance.
sku string No - If this mutation is a discount, this field will be set if the discount applies to a particular SKU.
campaignRuleUUID string No - UUID of the campaign rule responsible for this balance mutation. Will not be present in case of campaign-wide conditions.
campaignDescriptiveName string No - Descriptive name of the campaign result or condition that triggered this mutation. (requires JSON v2)

Card

Represents a Card object that can come back from a Search request. The fields that are available in this object will depend on the used SearchReturnFields in the Search request.

Parameter Type Required Default Description
brandDemographics string No - Custom Brand Demographics for the specified card. This will be a stringified JSON map where the keys are the internal names for the custom demographic fields, mapping directly to their corresponding values.
checkouts Array(HistoricCheckout) No - List of compact checkout overviews for historic checkouts for this card. (requires JSON v2)
mailings Array(Mailing) No - List of mailings that were sent to this card holder. This field is not guaranteed to be set, even if mailings are requested to be returned, as not all card holders might have received mailings.
emailBounced boolean No - Whether a BOUNCED event was logged on the card that was not followed by an UNBOUNCED event.
enrollmentDate string No - Date when this customer enrolled, only specified if the customer is enrolled and isEnrolled is set in the returnFields object. The format is yyyy-MM-dd, e.g. 2015-01-01. Not always available, contact Clutch if this property is needed but not available. (requires JSON v2)
customData string No - Custom data from the custom third party that was set for this card. This can be any string value. If there is a need to store multiple values, you could consider using a stringified JSON object as customData object. This data is not searchable, but can be returned if the card number is known.
recommendedProducts Array(RecommendedProduct) No - Recommended products for this card. (requires JSON v2)
segments Array(CardSegment) No - Matching segments. (requires JSON v2)
thirdPartyLinks Array(ThirdPartyCardProperties) No - Third party communication and opt in settings were set for this card. This will be an array of ThirdPartyCardProperties objects. Will not contain custom data property from ThirdPartyCardProperties object.
score CardScore No - Customer score (requires JSON v2)
balances Array(CardBalance) No - All balances associated with this card. If balances reach 0, they may be excluded from this list.
giverCustomer Customer No - The customer that gave this card, if this card was given by another customer.
alternateCustomer Customer No - An alternate customer that can be linked to this card. Can be used in the case of a secondary card holder.
pin string No - Card pin (requires JSON v2)
childCards Array(Card) No - Child cards that are attached to this card. (requires JSON v2)
coupons Array(CardCoupon) No - List of active coupons for this card. Max of 20 coupons returned. (requires JSON v2)
cardSetId string No - ID of the card set to which this card belongs. Will always be set on regular cards, will not be set on child cards.
customCardNumber string No - Custom card number (external card reference) for this card if it was set for the card and if this field was requested to be returned.
isEnrolled boolean No - Whether the primary customer linked to this card is flagged as enrolled into the loyalty program.
activationDate string No - Date when this card was activated. This field is not guaranteed to be set, even if the activation date was requested to be returned, as some cards may not be activated. Will be returned in the format yyyy-MM-dd HH:mm:ss (e.g. 2000-12-31 23:59:59). This field only includes the date, not the time of day. (requires JSON v2) (format: yyyy-MM-dd HH:mm:ss)
cardNumber string Yes - Card number, the main identifier of the card.
cardStatus string No - The status of this card. This field is only returned when includeInactive is set to true, and was allowed to be set to true.. Allowed values are only: Lost, Activated, Demo, Closed, Distributed, Transfer, Expired, Suspended, Inventory, Stolen
events Array(SearchResultEvent) No - List of events that are stored for this card.
customer Customer No - The primary customer linked to this card.

CardBalance

Represents a balance of a certain balance type that is available on a Card object.

Parameter Type Required Default Description
doesBalanceExpire boolean No - This field will only be returned if the searchRequest has balanceExpirations set to true in its return fields object. True indicates this object represents balance that expires, false indicates the represented balance does not expire. (requires JSON v2)
amount number Yes - The numerical amount of this balance object.
holdingTransactionId string No - If isHold is true, this field will contain a reference to the transaction responsible for holding this chunk of balance
balanceType string Yes - Balance type of this balance. If this is set to Currency or Custom, balanceCode is also required.. Allowed values are only: Points, Currency, Punches, Custom
convertedAmount number No - If the searchRequest specifies a convertToCurrency, and this balance represents an amount in the card’s native currency, this value will hold the current balance amount as it would be when converted to the specified target currency.
balanceCode string No - If the balance type is Currency or Custom, this field will contain the currency code or custom code assigned to this balance type
scale integer No - The amount of decimals used for this value type. When updating the balance of this value type, only send in amounts that will not cause the balance to have more decimals than the maximum amount allowed amount. If scale is set to 2, updating balance with 0.1 or for instance 0.01 is allowed, but updating balance with 0.001 is not.
isHold boolean No false This flag is set to true if this balance represents a chunk of a balance that is reserved by a hold transaction
balanceExpiration integer No - Expiration of this balance, the number of milliseconds since January 1, 1970, 00:00:00 GMT. This field is only included if doesBalanceExpire is specified and set to true. (requires JSON v2)
balanceActiveDate integer No - Active date of this balance, the number of milliseconds since January 1, 1970, 00:00:00 GMT. This field is only included if this balance object represents balance that is not yet available for redemption. These delayed balance objects will only be returned if delayedBalances is set to true in the request. (requires JSON v2)

CardBalanceAmount

This object represents an amount in a certain balance type that needs to be added to or removed from a card.

Parameter Type Required Default Description
amount number No - Numerical balance amount. Should always be positive, unless this is a deliberate negative issuance/redemption inside an adjustment transaction.
balanceType string Yes - The type of balance that this amount represents.. Allowed values are only: Points, Currency, Punches, Custom
balanceCode string No - If the balance type is Currency or Custom, this field indicates the currency code or custom code of the balance. This field should not be specified, unless balanceType is Currency or Custom, in which case this field is required.
convertToMainCurrency boolean No - In case of redemptions, this variable can optionally be set to true if the specified amount should be converted from the currency specified in the request and actually redeemed from the balance in the native currency on the card.

CardCoupon

Compact representation of a coupon on a card.

Parameter Type Required Default Description
redemptionDate string No - Date when this coupon was redeemed. (format: yyyy-MM-dd HH:mm:ss)
issuedDate string No - Date when this coupon was issued. (format: yyyy-MM-dd HH:mm:ss)
couponId string No - Coupon ID.
expirationDate string No - Date when this coupon expires. (format: yyyy-MM-dd HH:mm:ss)

CardHistoryRequest

Used to place CardHistory requests, which can be used to get a list of historic transactions for a specific card / customer.

Parameter Type Required Default Description
beginDate string No - Optional, the begin date of the requested card history report. If specified, only activity at or after this moment will be returned. Format as: yyyy-MM-dd HH:mm:ss, e.g. 2000-01-01 00:00:00 (format: yyyy-MM-dd HH:mm:ss)
sortMostRecentFirst boolean No true Optional, defaults to true. True means most recent results will be sent first. False means the oldest results will come first. (requires JSON v2)
offset integer No 0.0 Optional, defaults to 0, the amount of matching transactions to skip before returning results. Value should not be smaller than 0. Value should not be larger than 1000. (requires JSON v2)
endDate string No - Optional, the end date of the requested card history report. If specified, only activity at or before this moment will be returned. Format as: yyyy-MM-dd HH:mm:ss, e.g. 2000-01-01 00:00:00 (format: yyyy-MM-dd HH:mm:ss)
maxResults integer No 20.0 Optional, defaults to 20, maximum amount of results to obtain in one request. Value should not be smaller than 1. Value should not be larger than 100. (requires JSON v2)
includeCampaignData boolean No false Optional, defaults to false, whether or not campaign data should be included in the mutation objects. If set to true, this will only work if maxResults is set to 20 or less. (requires JSON v2)
childCardNumber string No - Optional, defaults to undefined. If defined, only requests from this specific child card number will be shown. The default behaviour is to show all requests, from both the main card and all attached child cards. NOTE: The allocation of a child card is a request on the main card and is not included in the card history for a specific child card number.
splitHoldMutations boolean No false Optional, defaults to false. If true, the balance mutations of transactions are broken down into hold related mutations and regular mutations.
restrictTransactionTypes Array(string) No - Optional, defaults to undefined. If defined, only requests with these transaction types will be included in the results. (requires JSON v2)
includeExternalTransactionIds boolean No false Optional, defaults to false, whether or not external transaction IDs should be included in the response. If set to true, maxResults is not allowed to be more than 20. (requires JSON v2)
cardNumber string Yes - Card number to request the card activity history for. This field is required in all cases, also if a childCardNumber is specified.
includeMainBalanceUpdate boolean No false Optional, defaults to false. If true, the main balance update for the transactions is included.

CardHistoryResponse

Response from CardHistory requests.

Parameter Type Required Default Description
requestRef string Yes - Unique request reference, can be used for debugging or tracking individual requests / responses.
oldestTransaction string No - Date and time of the overall oldest transaction for the specified card, in the format yyyy-MM-dd HH:mm:ss. If it is not being returned and you would like to access this field, please contact Clutch. (requires JSON v2) (format: yyyy-MM-dd HH:mm:ss)
newestTransaction string No - Date and time of the overall most recent transaction for the specified card, in the format yyyy-MM-dd HH:mm:ss. If it is not being returned and you would like to access this field, please contact Clutch. (requires JSON v2) (format: yyyy-MM-dd HH:mm:ss)
success boolean Yes false Success flag, true means the request was successfully processed.
errorMessage string No - Error message, can be included if success is false. This field can provide some human-readable insights into the request failure.
errorCode integer No - Error code, will only be included if success is false. See the JSON API documentation for all possible error codes and their meanings.
matchCount integer No - Amount of transactions that match the conditions. (requires JSON v2)
transactionCount integer No - Total amount of transactions on the specified card, not restricted to only the matching transactions. If it is not being returned and you would like to access this field, please contact Clutch. (requires JSON v2)
transactions Array(HistoricTransaction) No - A list of all matching transactions. At most 100 transactions will be returned within the specified date range. Matching transactions will be shown in descending order of processed time.

CardScore

RFM scoring information for a card.

Parameter Type Required Default Description
scoreLabel string No - Label that goes with the overall score. (requires JSON v2)
monetaryScore number Yes - Monetary score, on a scale of 1 to 5. Has 3 decimals precision. (requires JSON v2)
recencyScore number Yes - Recency score, on a scale of 1 to 5. Has 3 decimals precision. (requires JSON v2)
frequencyScore number Yes - Frequency score, on a scale of 1 to 5. Has 3 decimals precision. (requires JSON v2)
totalScore number Yes - Overall score, on a scale of 0 to 100. Has 0 decimals precision. (requires JSON v2)

CardSegment

Describe a segment that a card is part of.

Parameter Type Required Default Description
name string Yes - Name of the segment.
description string No - Short description of the segment.
id string Yes - ID of the segment.

ChannelCategoryType

Represents a subscription category.

Parameter Type Required Default Description
optIn boolean Yes false Subscribed status for category.
category string Yes - The category of list for a channel.

ChannelKeyValuesType

Represents custom key values for a subscription.

Parameter Type Required Default Description
name string Yes - The attribute name of the key value.
value string Yes - The value.

ChannelSubscriptionRequest

Used to place ChannelSubscription requests used to retrive the a channel subscription entry.

Parameter Type Required Default Description
channel string Yes - Channel to manage subscription for.. Allowed values are only: phone, email
channelUser string Yes - Email address or phone number. Phone number must be in E164 format for numbers outside the US.

ChannelSubscriptionResponse

Response from ChannelSubscription request.

Parameter Type Required Default Description
customKeyValues Array(ChannelKeyValuesType) No - Optional list of custom brand values.
globalOptIn boolean No false Global subscription status.
requestRef string Yes - Unique request reference, can be used for debugging or tracking individual requests / responses.
transactionalOptIn boolean No false Boolean status for transactional channel communications.
success boolean Yes false Success flag, true means the request was successfully processed.
doubleOptIn boolean No false Boolean status for if double opt in is or was required.
errorMessage string No - Error message, can be included if success is false. This field can provide some human-readable insights into the request failure.
channel string No - Channel to manage subscription for.. Allowed values are only: phone, email
errorCode integer No - Error code, will only be included if success is false. See the JSON API documentation for all possible error codes and their meanings.
channelUser string No - Email address or phone number.
doubleOptInConfirmed boolean No false Boolean status for if double opt in has been confirmed.
categories Array(ChannelCategoryType) No - Optional subscription status of sub categories.

CheckoutKeyValue

As part of a Checkout request, 0..n of these custom key/value pairs can be sent in. Each entry consists of a key and a value, and multiple entries with the same key and/or value are allowed to be sent in at once.

Parameter Type Required Default Description
value string Yes - Value for the specified key. Should always be in string format
key string Yes - Key name. Should always be in string format

CheckoutLookupRequest

Used to place CheckoutLookup requests, which can be used to find information about a specific previous checkout.

Parameter Type Required Default Description
checkoutTransactionId string Yes - The transaction ID of the checkout to look up. If a checkout-setup transaction was used and linked to the checkout-complete call, use the transaction ID of the checkout-complete API call.

CheckoutLookupResponse

Response from CheckoutLookup request.

Parameter Type Required Default Description
checkoutTotalBeforeDiscount number No - Checkout total before any discounts are applied, based on checkoutTotal in the original request, otherwise based on the sum of SKU prices.
skus Array(CheckoutProduct) No - All SKUs that were sent in as part of the original checkout.
childCardNumber string No - Child card number that was used in this request. Field will not be present for anonymous checkouts or checkouts that didn’t specify a child card number.
errorMessage string No - Error message, can be included if success is false. This field can provide some human-readable insights into the request failure.
errorCode integer No - Error code, will only be included if success is false. See the JSON API documentation for all possible error codes and their meanings.
terminalId string No - Terminal ID (external) at which this checkout was executed. This field may not be included for older checkouts and will require the latest version of the JSON API to be active. (requires JSON v2)
isVoided boolean No false Whether this checkout has been voided already. This field may not be included for older checkouts and will require the latest version of the JSON API to be active. (requires JSON v2)
customKeyValues Array(CheckoutKeyValue) No - Custom key-value pairs that were optionally sent in for custom campaign triggering. This entire array is optional. This field will only be returned for requests placed with the new JSON API. If the field does not come back while you were expecting this, please contact Clutch support. (requires JSON v2)
balanceMutations Array(CampaignBalanceMutation) No - All balance mutations that were caused by campaigns that were active during this checkout. Will contain hypothetical balance updates in case of a checkout setup request.
requestRef string Yes - Unique request reference, can be used for debugging or tracking individual requests / responses.
locationId string No - Location ID (external) at which this checkout was executed. This field may not be included for older checkouts and will require the latest version of the JSON API to be active. (requires JSON v2)
success boolean Yes false Success flag, true means the request was successfully processed.
paymentMethods Array(PaymentMethod) No - The payment methods that were used in this checkout. If this was a two-stage locking checkout complete call that specified payment methods in the checkout complete stage, those will be shown instead of the ones from the checkout setup call. (requires JSON v2)
totalDiscount number No - Total discount given based on campaigns.
externalTransactionId string No - The external transaction ID that was sent in for this transaction, if one was specified in the source request. This field will only be returned for requests placed with the new JSON API. If the field does not come back while you were expecting this, please contact Clutch support. (requires JSON v2)
referringCardNumber string No - The referring customer’s card number. (requires JSON v2)
cardNumber string No - Card number of the loyalty card that was used in this request. Field will not be present for anonymous checkouts.

CheckoutProduct

Represents the purchase of a certain amount of a specific SKU in a checkout. The purchase of multiple SKUs with the same unit price within one checkout can be combined into one CheckoutProduct. Can be considered equivalent to a checkout 'line item’.

Parameter Type Required Default Description
unitPrice number No 0.0 Price per unit of this product that was paid. Product total is unitPrice * amountPurchased. Should be a positive number, larger than or equal to 0. If you discount unit prices outside of Clutch campaigns and do not send them in with preDiscounts, send in the price after your own discount. Do not include any Clutch-triggered discounts in this price though.
amountPurchased number No 1.0 Product quantity that was purchased. Should be a positive number, larger than or equal to 0.
unitCost number No - Cost price per unit of this product for reporting purposes, will override unit cost that was specified in your catalog data. If specified, should be equal to or greater than 0 - it can be smaller than 0, but this is not recommended.
sku string Yes - SKU that identifies the product. Should be a non-empty value.

CheckoutRequest

Used to place Checkout requests, which should be called after every customer checkout, both in-store and online. This should also be called for anonymous checkouts, where no card is used.

Parameter Type Required Default Description
forcePinValidation boolean No false If set to true, a valid pin is always required for the used loyalty card. Anonymous checkouts will not be allowed if this is set to true.
cancelSetup boolean No false Optional. If set to true, this API call will be ignored and the outstanding checkout setup lock on the current card for the specified setup transaction ID will be released immediately.
useParentBalancesOnly boolean No false If you are using a childCardNumber, set this property to true to indicate that any balance mutation happening in this API call should not happen on the child card, but on the parent card instead. (requires JSON v2)
childCardNumber string No - Child card number, can be specified to modify balance on a child card inside the root card. (requires JSON v2)
trigger string No checkout Checkout trigger, determines what prompted this API call. This defaults to checkout, which is the only allowed value for incoming API calls at the moment.. Allowed values are only: date, social, checkout
lockExcludedValueTypes Array(ValueType) No - If lockSetupDuration is set to >0, but you want to be able to update balances of certain value types anyway, use this parameter to specify all value types of which balance updates should be allowed while the card is locked in a checkout.
checkoutTotal number No - Total amount spent for this transaction, used for campaign processing. Optional - if left out, this will be calculated from the products that are passed in. Should be less than 10 million. If preDiscounts are included in this request, the checkoutTotal should be the total before any of those preDiscounts are applied. Value should not be larger than 10000000.
preDiscounts Array(PreDiscount) No - Discounts that were already issued, outside of the Clutch campaign logic. (requires JSON v2)
lockSetupDuration integer No 0.0 Amount of seconds to lock the card used in this checkout, preventing concurrent checkouts or modifications. Optional, will be ignored unless value is larger than 0. If the value is ignored, the setup will not be a locking setup and cannot be used to hard-link to a checkout complete call. Only applies when isSetup is true. The lock will be reset when the checkout completes or cancels. When this field is set to a >0 value, you must specify a cardNumber in the request. Value should not be smaller than 0.
products Array(CheckoutProduct) No - All product purchased as part of this checkout. In case a locking checkout setup call is used, the products only have to be specified on the setup call. The checkout complete call will use the products from the setup in this case.
customKeyValues Array(CheckoutKeyValue) No - Custom key-value pairs that can optionally be used for custom campaign triggering. This entire array is optional.
returnBalanceMutations boolean No false Set to true to obtain a list of detailed balance mutation information for all balance updates and discounts.
returnBalances boolean No false Set to true to obtain balance data for the cardNumber that was used after this checkout is processed. If no card number is specified, no balances will be returned.
recommendationAmount integer No - Amount of product recommendations to return. This functionality is not available by default, please contact Clutch support for access. Value should not be smaller than 0. Value should not be larger than 20. (requires JSON v2)
pin string No - Pin for the loyalty card, only used if pin validation is needed (forcePinValidation=true).
coupons Array(string) No - Optional, all coupon IDs of the coupons that should be used for this checkout. At most 10 coupons can be specified. The same coupon cannot be used by more than one API call concurrently, this will result in a concurrent access error. For a locking checkout setup, the relevant coupons will also be reserved.
paymentMethods Array(PaymentMethod) No - This parameter can be used to specify how the customer paid for this checkout. Payment methods can be specified during a standalone checkout or checkout setup call, to potentially include them in campaign processing. If payment information is not known or complete during a checkout setup API call, it can also be sent in during the checkout complete phase. In this case, send in all payment methods relevant to the checkout during the checkout complete call. Payment method information during a checkout complete call for a two-stage checkout will not have any effect on campaign processing or redemptions made from payment methods specified during the checkout setup, but simply overwrite the payment methods that are stored for reporting purposes and lift calculation.
relatedSetupTransactionId string No - Optional, will be ignored unless isSetup is false. If set, will not execute the checkout, but just execute all actions and mutations shown in the locking setup transaction indicated by its transaction ID, as it was returned in the checkout setup API response. Can also be set in combination with cancelSetup set to true. If the checkout was set up using a non-empty card number, a subsequent linked checkout-complete request must also send in the card number, even if relatedSetupTransactionId is specified. Do not include this field unless the checkout setup was locking.
failOnUnusedCoupons boolean No true By default, the request will fail if coupons are specified that are not used by campaigns. Set this field to false if a checkout request should not fail if not all coupons that are sent in are actually used. (requires JSON v2)
referringCardNumber string No - Referring customer’s card number. If it’s specified, this must be an existing card number. In case of two-stage checkouts, this should be specified on the checkout setup call only. (requires JSON v2)
removeBlockingCoupons boolean No false If this field is set to true, coupons that are not allocated, have already been used, have been reserved by another API call or are not valid for the current card number will be removed silently. If this field is not specified or set to false, such coupons will cause the checkout to fail with error code 27 (invalid coupons).
cardNumber string No - Card number of loyalty card used in this transaction. Leave field out for anonymous checkouts. This field is required for locking checkouts.
isSetup boolean No false Indicate whether this call is just the checkout setup or the checkout-complete call. A checkout-complete call (isSetup=false) can be linked to the checkout-setup transaction if the checkout-setup was locking and did not expire or get cancelled.

CheckoutResponse

Response from Checkout requests.

Parameter Type Required Default Description
checkoutTotalBeforeDiscount number No - Checkout total before any discounts are applied, based on checkoutTotal in request, or sum of SKU prices.
blockingCoupons Array(string) No - If this checkout is returning with success set to false and errorCode 27 (invalid coupons), this field will contain a list of the coupons that were preventing the checkout from executing. Also, if removeBlockingCoupons was set to true, this will contain a list of coupons that were removed before processing to prevent an error from being returned.
childCardNumber string No - Child card number of the loyalty card that was used in this request. Field will not be present for anonymous checkouts or checkouts that didn’t specify a child card number. (requires JSON v2)
errorMessage string No - Error message, can be included if success is false. This field can provide some human-readable insights into the request failure.
errorCode integer No - Error code, will only be included if success is false. See the JSON API documentation for all possible error codes and their meanings.
issuedCouponIDs Array(string) No - Optional, i.e. is not always included in the response, this can contain an array of issued coupon IDs if the checkout was a checkout complete call and the underlying campaigns issued any coupons.
transactionId string No - Use this for debug reference. The transaction ID will be unique for every API call.
recommendedProducts Array(RecommendedProduct) No - Recommended products. (requires JSON v2)
balances Array(CardBalance) No - All real balances for the specified loyalty card, at the end of this checkout. For checkout setup requests, this will not include any balance updates from campaigns. This will only be included in the response if returnBalances was set to true.
balanceMutations Array(CampaignBalanceMutation) No - All balance mutations that were caused by campaigns that were active during this checkout. Will contain hypothetical balance updates in case of a checkout setup request. This will only be included if returnBalanceMutations was set to true. Note: Will also contain balance mutations caused by payment methods.
requestRef string Yes - Unique request reference, can be used for debugging or tracking individual requests / responses.
success boolean Yes false Success flag, true means the request was successfully processed.
unusedCoupons Array(string) No - If this checkout is returning with success set to false and errorCode 52 (coupons not used), this field will contain a list of the coupons that were not used by campaigns. This field is also included if success is true, but some coupons that were sent in and were usable were not used by campaigns.
totalDiscount number No - Total discount given based on campaigns.
cardNumber string No - Card number of the loyalty card that was used in this request. Field will not be present for anonymous checkouts.
responseMessages Array(string) No - All messages that can be returned to the customer / end user - only used if campaigns trigger any of these.

CouponDetailsRequest

Used to place a couponDetails request, which can give information about the status of an individual coupon or change its state

Parameter Type Required Default Description
reserveUntil string No - If the action is set to reserve, this field is required and indicates the point in time until which this coupon will be unusable except by releaseReservation or useReservation. Format as: yyyy-MM-dd HH:mm:ss, e.g. 2000-01-01 00:00:00. This field can be at most 10 years into the future and cannot be in the past. (format: yyyy-MM-dd HH:mm:ss)
newCustomTags Array(string) No - Optional, if this value is present in the request and is not null, the custom tags of the specified coupon will be set to this value. If this value is an empty array, the custom tags will be reset. This value can be used with any action.
action string Yes - Action to take with the specified coupon. Allocated coupons can be flagged as used (use) or not yet used (unuse). For reserved usage, coupons can be reserved (reserve), reservations can be used (useReservation) or released (releaseReservation).. Allowed values are only: releaseReservation, use, reserve, details, unuse, useReservation
newAllowedCards Array(string) No - Optional, if this value is present in the request and is not null, the allowedWithCards field of the specified coupon will be set to this value. If this value is an empty array, the allowedWithCards fields will be reset. This value can be used with any action. An empty array means any card can use the coupon, an array with one or more card number means usage in checkouts is restricted to the indicated card numbers.
couponId string Yes - Coupon ID of the coupon to get details for. Must be a coupon that has not yet expired.
newExpirationDate string No - Optional, if this value is present in the request and is not null, the expiration date on the coupon will be updated to this date. Can only update expiration dates on coupons that haven’t expired yet. Format as: yyyy-MM-dd HH:mm:ss, e.g. 2000-01-01 00:00:00. Cannot be in the past. (format: yyyy-MM-dd HH:mm:ss)
cardNumber string No - Card number of loyalty card this coupon is allocated for. Optional field, only specify to update coupon expiration date or for when redeeming coupon.

CouponDetailsResponse

Response from a couponDetails request.

Parameter Type Required Default Description
reservedUntil string No - Optional, if the coupon’s usage is currently reserved, this will contain the coupon reservation end date in the format yyyy-MM-dd HH:mm:ss (format: yyyy-MM-dd HH:mm:ss)
requestRef string Yes - Unique request reference, can be used for debugging or tracking individual requests / responses.
customTags Array(string) No - Optional, can contain custom tags associated with the indicated coupon, if the coupon has custom tags associated with it.
success boolean Yes false Success flag, true means the request was successfully processed.
errorMessage string No - Error message, can be included if success is false. This field can provide some human-readable insights into the request failure.
errorCode integer No - Error code, will only be included if success is false. See the JSON API documentation for all possible error codes and their meanings.
isAllocated boolean No false Whether the coupon has been allocated already.
isDisabled boolean No false Whether the coupon has been disabled. Coupons are only disabled if they have been allocated as part of a two-stage locking checkout, but not yet enabled as the checkout has not yet been completed.
isUsed boolean No false Whether this coupon has been used already.
allowedWithCards Array(string) No - Optional, can contain a list of card numbers that are allowed to use this coupon. This field is only specified if the coupon has card restrictions on it.
expirationDate string No - Optional, if the coupon has an expiration date on it, this will contain the coupon expiration date in the format yyyy-MM-dd HH:mm:ss (format: yyyy-MM-dd HH:mm:ss)

CreateEventTypeRequest

Create a new custom event type defintion.

Parameter Type Required Default Description
sentiment integer No - The sentiment of this event definition - 0 for neutral, 1 for positive, -1 for negative.
groupType string No - Optional, the type for this event definition. Can be ECOM, EMAIL, SMS, DIRECT MAIL, IN STORE, FEEDBACK, SOCIAL, MILESTONE, OTHER. Will default to OTHER unless specified.
name string No - Optional, a descriptive name for this event type definition. If an event with the specified categoryId already exists, and the name field is specified, the name will be updated to this new value.
categoryId string Yes - Category ID to use for the event to be created.

CreateEventTypeResponse

Response object for createEventType requests.

Parameter Type Required Default Description
requestRef string Yes - Unique request reference, can be used for debugging or tracking individual requests / responses.
success boolean Yes false Success flag, true means the request was successfully processed.
errorMessage string No - Error message, can be included if success is false. This field can provide some human-readable insights into the request failure.
errorCode integer No - Error code, will only be included if success is false. See the JSON API documentation for all possible error codes and their meanings.

CustomDemographicFilter

Filter for a value of a custom brand demographics field.

Parameter Type Required Default Description
fieldName string Yes - Field name of the custom brand demographics field.
textValue string Yes - Expected text value for the given field. Specify this field is a text value is expected.

CustomEventProperty

Custom property that can be logged on an event

Parameter Type Required Default Description
value string Yes - Custom property’s value
key string Yes - Custom property key. This key will be unique within the event registration.

Customer

Represents a Customer object coming back from the API. For restrictions on each of the fields, see the CustomerUpdates object.

Parameter Type Required Default Description
birthday string No - Format is yyyy-MM-dd, e.g. 2015-01-01
lastName string No - -
country string No - ISO 3166-1 Country code, 2 characters
gender string No - Allowed values are only: F, M
address2 string No - Second address line
city string No - -
address1 string No - First address line
latitude number No - Latitude in degrees, value from 90 to -90. Positive values are north of the equator, negative values are south of the equator. Precision is 6 decimals.
firstName string No - -
flv integer No - FLV or Future Lifetime Value
mobilePhone string No - Mobile phone number in E164 format.
phone string No - Phone number in E164 format.
phonePref string No - Opt (I)n, Opt (O)ut for text messages. Allowed values are only: I, O
middleName string No - -
state string No - -
postal string No - -
mailPref string No - Opt (I)n, Opt (O)ut for post mail. Allowed values are only: I, O
isMobile string No - (Y)es, (N)o or empty. Allowed values are only: Y, N
email string No - -
emailPref string No - Opt (I)n, Opt (O)ut for email. Allowed values are only: I, O
anniversary string No - Format is yyyy-MM-dd, e.g. 2015-01-01
longitude number No - Longitude in degrees, value from 180 to -180. Positive values are east of the prime meridian, negative values are west of the prime meridian. Precision is 6 decimals.

CustomerUpdates

Represents an update request for one or more properties of a customer tied to a card. Any property that is specified is a field on the customer object that is requested to be updated, so do not specify values for fields that should not be updated.

Parameter Type Required Default Description
birthday string No - Birthday, in the format yyyy-MM-dd, e.g. 1900-01-01.
lastName string No - Last name, max length is 90 Value should not be longer than 90 characters.
country string No - Country code, max length is 2 Value should not be longer than 2 characters.
gender string No - Gender. Allowed values are only: F, M
address2 string No - Address line 2, max length is 100 Value should not be longer than 100 characters.
city string No - City, max length is 75 Value should not be longer than 75 characters.
mobileOperatorId string No - Mobile Operator Id, max length is 18. Open Market’s Operator ID or an empty string Value should not be longer than 18 characters.
address1 string No - Address line 1, max length is 100 Value should not be longer than 100 characters.
latitude number No - Latitude in degrees, value from 90 to -90. Positive values are north of the equator, negative values are south of the equator. Precision is 6 decimals. Value should not be smaller than -90. Value should not be larger than 90.
firstName string No - First name, max length is 40 Value should not be longer than 40 characters.
mobilePhone string No - Mobile phone number, max length is 18. Must be a valid phone number or an empty string Value should not be longer than 18 characters.
phone string No - Phone number, max length is 18. Must be a valid phone number or an empty string Value should not be longer than 18 characters.
middleName string No - Middle name, max length is 40 Value should not be longer than 40 characters.
state string No - State name, full name is allowed, max length is 75 Value should not be longer than 75 characters.
postal string No - Postal code, max length is 10 Value should not be longer than 10 characters.
anniversary string No - Anniversary, in the format yyyy-MM-dd, e.g. 2000-01-01.
email string No - Email address, max length is 320 Value should not be longer than 320 characters.
longitude number No - Longitude in degrees, value from 180 to -180. Positive values are east of the prime meridian, negative values are west of the prime meridian. Precision is 6 decimals. Value should not be smaller than -180. Value should not be larger than 180.

EventRegistration

Representation of a custom event that should be added to a card.

Parameter Type Required Default Description
payload string No - Optional, the variable-text payload attached to this event.
categoryId string Yes - High level ID for this event’s event type. The associated event type will always be 'CUSTOM’.
eventDate string No - Optional, specify a custom date and time for this new event. Format as: yyyy-MM-dd HH:mm:ss, e.g. 2000-01-01 00:00:00. If not specified, the current date / time will be used. (format: yyyy-MM-dd HH:mm:ss)

EventTypeDefinition

Represents an event type definition.

Parameter Type Required Default Description
sentiment integer No - The sentiment of this event definition - 0 for neutral, 1 for positive, -1 for negative.
groupType string No - the type for this event definition. Can be ECOM, EMAIL, SMS, DIRECT MAIL, IN STORE, FEEDBACK, SOCIAL, MILESTONE, OTHER
specificId string No - Lower level ID for this event’s event type.
name string No - Descriptive name of this event type.
modifiedDate string No - The date this event definition was last modified (format: yyyy-MM-dd HH:mm:ss)
active boolean No - Whether or not this event definition is active or archived.
eventType string Yes - Event type. E.g. for custom events, this will be CUSTOM.
categoryId string Yes - High level ID for this event’s event type.
createDate string No - The date this event definition was created (format: yyyy-MM-dd HH:mm:ss)

HistoricCheckout

Compact representation of a historic checkout for a card.

Parameter Type Required Default Description
externalReference string No - External reference to the original request.
isReturn boolean No false Indication if this was a return or a checkout. Will be true for returns and false for regular checkouts.
checkoutDate string No - Date when this checkout was executed. (format: yyyy-MM-dd HH:mm:ss)
mutations Array(CampaignBalanceMutation) No - Balance mutations that happened during this historic checkout. Will not include discounts, but only real balance mutations. Will not contain balance mutations from before this feature was released (mid 2016). (requires JSON v2)
transactionReference string No - Reference to the original request. For most brand configurations, this will be the requestRef.
locationId string No - External ID of the location that processed this checkout.
checkoutTotal number No - Checkout total, in the native currency of the processing location. In case of returns, this will be a negative number.

HistoricTransaction

Represents a transaction / API call that happened in the past.

Parameter Type Required Default Description
legacyType string No - Optional, this value will only be present for transactions coming from the legacy APIs, such as the SOAP API. The values map to the abbreviations for transaction types in the Web Services documentation. Calls to the JSON API will not have a legacyType assigned to them.. Allowed values are only: GI, PR, E, MR, LR, AH, I, GR, ER, R, EX, T, V, X, PI, MI, LI, TR
requestRef string No - RequestRef of the original request. Only present if the original request was placed with the same API version that is being used in the card history response.
isLegacy boolean Yes false Whether this transaction was placed through a legacy API call (e.g. through the SOAP API), or through this current API.
childCardNumber string No - Child card number used in this request. Will only be specified if there was a child card number. (requires JSON v2)
location string No - External location ID, the location where this transaction was initiated. Usually not returned. Please contact Clutch customer support if you want to use this field.
externalTransactionId string No - External transaction ID that was sent in with this request. (requires JSON v2)
transactionTime integer Yes - Date and time when this transaction executed. The value is the number of milliseconds since January 1, 1970, 00:00:00 GMT.
mainBalanceUpdate number No - The main balance update amount from this transaction. For an issuance, this will be the amount issued, for a redemption it will be the actual amount redeemed. For checkout API calls from this API, more balance mutation details are available through checkoutLookup.
transactionId string Yes - Transaction ID of this historic transaction. Even though these values are usually numerical, they can be any unordered alphanumerical value.
callType string No - Optional, this value can optionally be present for transactions coming from the new JSON API. It will only be set if the API call was one of the predefined types. If it is not being returned and you would like to access this field, please contact Clutch. (requires JSON v2). Allowed values are only: UPDATE_BALANCE, VOID_CHECKOUT, SEARCH, CHECKOUT_SETUP, UPDATE_ACCOUNT, REPORTING, CHECKOUT_COMPLETE, CHECKOUT_CANCEL, ALLOCATE, TRANSFER, RETURN_MERCHANDISE, VOID, ACCOUNT_HISTORY
balanceUpdates Array(HistoricTransactionBalanceUpdate) No - Optional, this property can optionally be present if the new JSON API is being used. It will only include high-level balance update information, not including any potential discounts. If it is not being returned and you would like to access this field, please contact Clutch. (requires JSON v2)
holdBalanceUpdates Array(HistoricTransactionBalanceUpdate) No - Optional, this property can optionally be present if the new JSON API is being used. If the request parameter 'splitHoldMutations’ is set to true this property will contain all balance update information for held balances

HistoricTransactionBalanceUpdate

This model represents a main balance update that was executed during a historic transaction.

Parameter Type Required Default Description
campaignRuleName string No - Can contain the name of the campaign rule that triggered this balance update. (requires JSON v2)
amount number Yes - The amount of this balance update. This amount is positive for issuances and negative for redemptions.
balanceType string Yes - The balance type of this balance update.. Allowed values are only: Points, Currency, Punches, Custom
balanceCode string No - This is only defined for Currency or Custom balance types, to further define the balance type that was affected by this balance mutation.
campaignResultName string No - Can contain the name of the campaign result that triggered this balance update. (requires JSON v2)
campaignName string No - Can contain the name of the campaign that triggered this balance update. (requires JSON v2)
campaignConditionName string No - Can contain the name of the campaign condition that triggered this balance update. (requires JSON v2)
balanceActiveDate integer No - Active date of this balance, the number of milliseconds since January 1, 1970, 00:00:00 GMT. This field is only included if this balance object represents balance that was not yet available for redemption during the time of the original API call that issued this balance. NOTE: This field will not change over time, the balanceActiveDate may be in the past compared to the cardHistory call. (requires JSON v2)

ListEventTypesRequest

Request to get all custom event types that have been set up for this brand

Parameter Type Required Default Description
offset integer No 0.0 Offset, start at this event. Events are always sorted oldest to newest. This fields defaults to 0. Value should not be smaller than 0. Value should not be larger than 100000. (requires JSON v2)
limit integer No 1000.0 Return at most this many events started at the specified offset. Defaults to 1000, which is also the maximum allowed value. Value should not be smaller than 10. Value should not be larger than 1000. (requires JSON v2)

ListEventTypesResponse

Response for listEventTypes call, returns a list of all event types that have been set up for this brand

Parameter Type Required Default Description
requestRef string Yes - Unique request reference, can be used for debugging or tracking individual requests / responses.
success boolean Yes false Success flag, true means the request was successfully processed.
errorMessage string No - Error message, can be included if success is false. This field can provide some human-readable insights into the request failure.
errorCode integer No - Error code, will only be included if success is false. See the JSON API documentation for all possible error codes and their meanings.
eventTypes Array(EventTypeDefinition) Yes - List of all event types that were set up

ListRequestsRequest

Request for listRequests, can list all requests that match a certain externalTransactionId.

Parameter Type Required Default Description
externalTransactionId string Yes - External transaction ID to search for. Will return anywhere from 0 to many matching requestRefs, depending on how many requests used this externalTransactionId.

ListRequestsResponse

Response for listRequests call. Will also return successfully if no requests matched.

Parameter Type Required Default Description
requestRef string Yes - Unique request reference, can be used for debugging or tracking individual requests / responses.
requestRefs Array(string) Yes - List of requestRefs that match the requested externalTransactionID.
success boolean Yes false Success flag, true means the request was successfully processed.
errorMessage string No - Error message, can be included if success is false. This field can provide some human-readable insights into the request failure.
errorCode integer No - Error code, will only be included if success is false. See the JSON API documentation for all possible error codes and their meanings.

ListSubscriptionListsRequest

Used to retrieve a brand’s subscription lists by communication channel type.

Parameter Type Required Default Description
communicationChannelType string Yes - The communication channel type. (Phone or email.). Allowed values are only: phone, email

ListSubscriptionListsResponse

Response from BrandSubscriptionList requests.

Parameter Type Required Default Description
requestRef string Yes - Unique request reference, can be used for debugging or tracking individual requests / responses.
success boolean Yes false Success flag, true means the request was successfully processed.
errorMessage string No - Error message, can be included if success is false. This field can provide some human-readable insights into the request failure.
errorCode integer No - Error code, will only be included if success is false. See the JSON API documentation for all possible error codes and their meanings.
subscriptionLists Array(SubscriptionListInfo) No - List of subscription lists and their info.

ListValueTypesRequest

Used to place ListValueTypes requests, which can be used to list all value types available for a certain card or a certain card set.

Parameter Type Required Default Description
lookupCardNumber string No - Card number to look up the value types for. Optional - either this field or cardSetId can be specified.
cardSetId string No - ID of card set for which to look up the value types. Optional - if this field is set, cardNumber does not have to be specified. If cardNumber is set, don’t include this field in the request.

ListValueTypesResponse

Resposne from ListValueType requests.

Parameter Type Required Default Description
requestRef string Yes - Unique request reference, can be used for debugging or tracking individual requests / responses.
success boolean Yes false Success flag, true means the request was successfully processed.
errorMessage string No - Error message, can be included if success is false. This field can provide some human-readable insights into the request failure.
errorCode integer No - Error code, will only be included if success is false. See the JSON API documentation for all possible error codes and their meanings.
valueTypes Array(ValueTypeResult) No - All available value types.

Mailing

Mailing data, represents one mailing that was sent to a card holder.

Parameter Type Required Default Description
mailingListId string Yes - Mailing list ID, identifies the mailing list.
mailingRunId string Yes - Mailing run ID, this is a unique identifier that is generated every time a mailing list is mailed out.
sentAt integer Yes - Date and time when this mailing was sent. The value is the number of milliseconds since January 1, 1970, 00:00:00 GMT.

PaymentMethod

Represents a payment that was made as part of a checkout. Specify at least either the amount and paymentType yourself, an updateBalanceRequestRef or redeemBalance = true.

Parameter Type Required Default Description
countAsDiscount boolean No false If specified and set to true, this payment method will be considered a discount for campaign processing and reporting purposes. Defaults to false. (requires JSON v2)
amount number No - The amount that was paid using the specified payment type. Needs to be a positive amount. Value should not be smaller than 0.
balanceType string No - The type of balance that this amount represents. Only specify this if redeemBalance is true. (requires JSON v2). Allowed values are only: Points, Currency, Punches, Custom
balanceCode string No - If the specified balanceType is Currency or Custom, this field indicates the currency code or custom code of the balance. This field should not be specified, unless balanceType is Currency or Custom, in which case this field is required. (requires JSON v2)
updateBalanceRequestRef string No - If a previous updateBalance request should be considered a payment method for this checkout, you can reference it by its requestRef. If no paymentType is specified, it will be set to gift in case the updateBalance redeemed currency, and loyalty otherwise. If no amount is specified, it will be set to the amount of the updateBalance request. NOTE: If specified, this should always point to an updateBalance call from the same card that is specified in the checkout request. (requires JSON v2)
checkoutPaymentAmount number No - If this payment method is in a different balance type (e.g. Points) than the checkout’s balance type, this field can be used to specify how much this payment method pays of the checkout total. If not specified, will default to the value from the amount field. Example: 5 points are used to pay for $2 of the checkout, the amount field contains 5 and the checkoutPaymentAmount is 2. (requires JSON v2)
paymentType string No - The type of payment that was used, used for reporting purposes. If not specified and updateBalanceRequestRef is defined or redeemBalance is set to true, that will be used to choose between loyalty and gift.. Allowed values are only: Giftcard, Loyaltycard, Deferred, Check, Visa, DebitCard, Discover, Voyager, Cash, MasterCard, WrightExpress, GuaranteedCheck, PHH, DinersClub, ElectronicCheck, AmericanExpress, Creditcard, BrandedCreditCard, Other
redeemBalance boolean No false If specified as true, this payment method will actually perform a balance redemption from the card used in this request. If specified as true, balanceType and balanceCode indicate the type of balance to redeem and the amount field will specify how much to redeem. Do not set this field to true if you are also sending in updateBalanceRequestRef. (requires JSON v2)

PreDiscount

Represents a discount that was issued outside of the Clutch campaign logic.

Parameter Type Required Default Description
amount number Yes - Amount of this discount. Amount should be positive.

ProcessMessageRequest

Used to place processMessage API requests, which can be used to process incoming messages for a card

Parameter Type Required Default Description
message string Yes - Incoming message content.
cardNumber string Yes - Card number for which the incoming message should be processed.

ProcessMessageResponse

Response from processMessage requests.

Parameter Type Required Default Description
requestRef string Yes - Unique request reference, can be used for debugging or tracking individual requests / responses.
success boolean Yes false Success flag, true means the request was successfully processed.
errorMessage string No - Error message, can be included if success is false. This field can provide some human-readable insights into the request failure.
errorCode integer No - Error code, will only be included if success is false. See the JSON API documentation for all possible error codes and their meanings.
triggeredRuleCount integer No 0.0 The number of campaign rules that were triggered.

ReactivateRequest

Used to reactivate a suspended card.

Parameter Type Required Default Description
forcePinValidation boolean No false If set to true, a valid pin is always required for the specified card. This pin always applies to the card specified by cardNumber. Pin validation is not used for the card indicated by oldCardNumber
pin string No - Pin for the specified card, only used if pin validation is needed.
cardNumber string Yes - The card number to reactivate.

ReactivateResponse

Used to reactivate a suspended card.

Parameter Type Required Default Description
requestRef string Yes - Unique request reference, can be used for debugging or tracking individual requests / responses.
success boolean Yes false Success flag, true means the request was successfully processed.
errorMessage string No - Error message, can be included if success is false. This field can provide some human-readable insights into the request failure.
errorCode integer No - Error code, will only be included if success is false. See the JSON API documentation for all possible error codes and their meanings.

RecommendedProduct

Represents a recommendation for a SKU.

Parameter Type Required Default Description
name string No - Product name.
sku string Yes - SKU that identifies the product.

RequestLookupRequest

Used to place RequestLookup requests, which can be used to find information about a specific previous request.

Parameter Type Required Default Description
requestRef string Yes - The requestRef of the request to look up.
splitHoldMutations boolean No false Optional, defaults to false. If true, the balance mutations of transactions are broken down into hold related mutations and regular mutations.

RequestLookupResponse

Response from RequestLookup request.

Parameter Type Required Default Description
note string No - Note that was sent in with the original request. (requires JSON v2)
checkoutTotalBeforeDiscount number No - If this call was a checkout call, the checkout total before any discounts are applied, based on checkoutTotal in request, or sum of SKU prices. (requires JSON v2)
childCardNumber string No - Child card number used in this request, will not be present for anonymous requests or requests that didn’t include a child card number. (requires JSON v2)
errorMessage string No - Error message, can be included if success is false. This field can provide some human-readable insights into the request failure.
errorCode integer No - Error code, will only be included if success is false. See the JSON API documentation for all possible error codes and their meanings.
terminalId string No - Terminal header that was sent in. This field may not be included for older requests and will require the latest version of the JSON API to be active. (requires JSON v2)
isVoided boolean No false Whether this request has been voided already. This field may not be included for older requests and will require the latest version of the JSON API to be active. (requires JSON v2)
holdBalanceMutations Array(CampaignBalanceMutation) No - Optional, will only be populated if the 'splitHoldMutations’ request param is set to true. Contains all hold related balance mutations and/or discounts that were executed in the requested API call. Will not contain hypothetical balance updates in case of a checkout setup request. Will contain references to campaigns if the mutations were triggered by campaigns. NOTE: This field does not exist for transactions placed before July 2016. (requires JSON v2)
callType string No - Optional, this value can optionally be present for transactions coming from the new JSON API. It will only be set if the API call was one of the predefined types. If it is not being returned and you would like to access this field, please contact Clutch. (requires JSON v2). Allowed values are only: UPDATE_BALANCE, VOID_CHECKOUT, SEARCH, CHECKOUT_SETUP, UPDATE_ACCOUNT, REPORTING, CHECKOUT_COMPLETE, CHECKOUT_CANCEL, ALLOCATE, TRANSFER, RETURN_MERCHANDISE, VOID, ACCOUNT_HISTORY
requestErrorCode integer No - The error code that was sent back for this request, if there was one. This field will not be specified if the specified request was successful. (requires JSON v2)
balanceMutations Array(CampaignBalanceMutation) No - All balance mutations and/or discounts that were executed in the requested API call. Will not contain hypothetical balance updates in case of a checkout setup request. Will contain references to campaigns if the mutations were triggered by campaigns. NOTE: This field does not exist for transactions placed before July 2016. (requires JSON v2)
requestRef string Yes - Unique request reference, can be used for debugging or tracking individual requests / responses.
locationId string No - Location header that was sent in. This field may not be included for older requests and will require the latest version of the JSON API to be active. (requires JSON v2)
success boolean Yes false Success flag, true means the request was successfully processed.
requestDate string No - Date/time when this request was executed. (format: yyyy-MM-dd HH:mm:ss)
totalDiscount number No - If this call was a checkout call, the total discount given based on campaigns. (requires JSON v2)
externalTransactionId string No - External transaction ID as it was sent in with the original request. (requires JSON v2)
cardNumber string No - Card number used in this request, will not be present for anonymous requests. (requires JSON v2)

ReturnRequest

Used to place returnMerchandise requests, which can be used to notify the Clutch API of returned merchandise, being sales with negative totals.

Parameter Type Required Default Description
returnedProducts Array(CheckoutProduct) No - Products that are returned. Only required fields on each CheckoutProduct object are sku and amountPurchased. For amountPurchased, specify the amount that is returned. In addition, unitPrice can be specified.
usedCouponResets string No OnlyOnFullReturn Flag to indicate if and when to reset coupons used by the original checkout. If this is set to always, coupons will always be reset. If this is set to never, they will never be reset. Set to OnlyOnFullReturn if the used coupons should be reset only if this return (combined with any possible previous returns for the same checkout) totals the entire sum of the original checkout. Defaults to OnlyOfFullReturn. (requires JSON v2). Allowed values are only: OnlyOnFullReturn, Never, Always
failIfOverReturn boolean No true Whether requests should fail if they return more products than specified on the original checkout, combined from this return call and any other possible previous returns for the same checkout. If this is set to false (or not specified), and this return tries to return too many products, the request will fail. This flag defaults to false. This flag will be ignored if no checkoutRequestRef has been specified, or if the referenced checkout was anonymous. Will compare the total value of returned products plus additionalReturnAmount compared to the original checkout and also verify the quantities sent in per SKU. (requires JSON v2)
checkoutRequestRef string No - RequestRef of the original request. Should be set if this return is linked to a known checkout. If this field is specified, it is required to also specify the cardNumber used in the original checkout. In case the original checkout used two-stage locking, use the requestRef of the checkout complete API call.
failIfCouponsUsed boolean No true If disabledIssuedCoupons is true (default value) and the original checkout issued coupons that had since been used, make the request fail (because it can’t disable the coupons anymore). This flag defaults to true.
reversePayments boolean No false Whether payments should be reversed. Will log reverse for all payments and those flagged as redeemBalance = true or with an updateBalanceRequestRef will be reversed fully. Note: this flag should not be set to true more than once for a given source checkout, to prevent over-returning. (requires JSON v2)
childCardNumber string No - The child card number that was used in the original request. If a child card number was used in the original request, the child card number specified in this request has to match. If this field is specified, the cardNumber field also has to be specified.
simulateOnly boolean No false Flag to indicate if this is a real return or just a simulation. If it’s just a simulation, nothing is actually executed, but the request is only simulated and the results are returned.
additionalReturnAmount number No - Additional amount of the original checkout total that is being returned, excluding the part of the checkout that is explained by SKUs with a unitPrice and amountPurchased specified in the returnProducts property already.
removeCustomEvents boolean No false Whether any custom events that were created by logEvent campaign results on the original checkout should be removed by this return, if they had not been removed by a potential previous return for the same checkout. Defaults to false.
cardNumber string No - Card number of loyalty card used in this transaction. Leave field out for anonymous returns. This field is required if a checkoutRequestRef is specified.
disableIssuedCoupons boolean No true Whether coupons that were issued as part of the original checkout should be disabled. Defaults to true

ReturnResponse

Response from returnMerchandise requests.

Parameter Type Required Default Description
requestRef string Yes - Unique request reference, can be used for debugging or tracking individual requests / responses.
success boolean Yes false Success flag, true means the request was successfully processed.
errorMessage string No - Error message, can be included if success is false. This field can provide some human-readable insights into the request failure.
errorCode integer No - Error code, will only be included if success is false. See the JSON API documentation for all possible error codes and their meanings.

SearchFilters

Represents the filters used to search cards / customers.

Parameter Type Required Default Description
lastName string No - Use this filter to find all cards where the last name of the primary customer linked to the card matches with the specified value.
firstNamePrefix string No - Use this filter to find customers by a first name prefix. This filter can generally only be used to restrict search results to cards matching this first name prefix. If both firstNamePrefix and lastNamePrefix are defined and are both at least 3 characters long (or shorter if the name on the intended card is shorter than 3 characters), no other filters are required to be specified. This functionality is not available by default, please contact Clutch support for access. (requires JSON v2)
customDemographics Array(CustomDemographicFilter) No - Use this filter to look for cards with a certain value (requires JSON v2)
firstName string No - Use this filter to find all cards where the first name of the primary customer linked to the card matches with the specified value.
lastNamePrefix string No - Use this filter to find customers by a last name prefix, otherwise similar to firstNamePrefix. This functionality is not available by default, please contact Clutch support for access. (requires JSON v2)
excludeCardSetIds Array(string) No - Use this filter to exclude cards from the specified card sets. This filter can never be used as the only filter, as it will generally match too many cards by itself. Only specify this on the main filters, do not use it in child card filters.
mobilePhone string No - Use this filter to find all cards where the mobile phone number of the primary customer linked to the card matches with the specified value. The value should be in an E-164 format. If a value is sent in in any other format, it will be attempted to be converted to E164 format, but this is not recommended. (requires JSON v2)
phone string No - Use this filter to find all cards where the phone number of the primary customer linked to the card matches with the specified value. The value should be in an E-164 format. If a value is sent in in any other format, it will be attempted to be converted to E164 format, but this is not recommended.
cardSetId string No - Use this filter to restrict search results to cards from the specified card set. This filter can never be used as the only filter, as it will generally match too many cards by itself. Only specify this on the main filters, do not use it in child card filters.
customCardNumber string No - The custom card number, being a custom reference to the card to look up. This custom card number can be set through updateAccount and can be used to find cards.
cardNumber string No - The card number to look up. When using this filter, the other filters should most likely not be used.
email string No - Use this filter to find all cards where the email address of the primary customer linked to the card matches with the specified value.
programTypes Array(string) No - If specified, only cards from card sets from programs with these program types will be allowed. If not specified, which program types are allowed will depend on the brand settings. If there is no brand setting to specify which program types are allowed by default, any program type is allowed. Only specify this on the main filters, do not use it in child card filters.

SearchRequest

Used to place Search requests, when searching for cards / customers.

Parameter Type Required Default Description
forcePinValidation boolean No false If set to true, a valid pin is always required. This field will be ignored unless the card number has been specified in the filters section.
includeInactive boolean No false Whether inactive cards should be returned as well. If not specified or set to false, only active cards will be returned. Setting this value to true is only allowed when searching with a cardNumber or customCardNumber and nothing else.
convertToCurrency string No - The target conversion to which the default currency on the resulting cards should be converted.
offset integer No 0.0 Indicate the offset of the returned rows. If set to 1, the first row will be skipped in the output. Value should not be smaller than 0. Value should not be larger than 1000.
pin string No - Pin for the card, only used if pin validation is needed.
filterLogicAnd boolean No true Whether the filters should be applied with boolean AND logic or not. If set to true, use AND logic, if set to false, use OR logic. (requires JSON v2)
childFilters SearchFilters No - Use the childFilters to filter on specific properties of child cards. If child filters are used, it is usually recommended to specify childCards to be returned in the returnFields field.
limit integer No 10.0 How many results to return. Value should not be smaller than 1. Value should not be larger than 25.
filters SearchFilters Yes - Use the SearchFilters object to specify the filters you want to use to find a card. If you only use cardNumber or customCardNumber the results will be real-time, otherwise they could be cached.
returnFields SearchReturnFields No - If specified, this object can be used to indicate which additional information should be returned for matching cards.

SearchResponse

Response from Search requests.

Parameter Type Required Default Description
usedCache boolean No false Whether a slightly delayed cache was used to perform this search. Balance information will never be cached, but all other data can be cached. Cached data is usually refreshed within a minute. If searching on just the card number or custom card number, the cache will never be used.
requestRef string Yes - Unique request reference, can be used for debugging or tracking individual requests / responses.
cards Array(Card) No - Results from the search: cards that matched the filters.
success boolean Yes false Success flag, true means the request was successfully processed.
errorMessage string No - Error message, can be included if success is false. This field can provide some human-readable insights into the request failure.
errorCode integer No - Error code, will only be included if success is false. See the JSON API documentation for all possible error codes and their meanings.

SearchResultEvent

Represents an event that is stored on a card.

Parameter Type Required Default Description
mailingSpecificId string No - In case the eventType is BOUNCED, this field can hold the specificId of the original mailing event.
customProperties Array(CustomEventProperty) No - Optional list of custom properties that were logged on this event.
specificId string No - Lower level ID for this event’s event type.
payload string No - Optional, the variable-text payload attached to this event.
eventType string Yes - Event type. E.g. for custom events, this will be CUSTOM.
mailingCategoryId string No - In case the eventType is BOUNCED, this field can hold the categoryId of the original mailing event.
categoryId string Yes - High level ID for this event’s event type.
eventDate integer Yes - Date and time when this event was logged. The value is the number of milliseconds since January 1, 1970, 00:00:00 GMT.

SearchReturnFields

Describes which fields should be returned from a Search request.

Parameter Type Required Default Description
delayedBalances boolean No false If balances is set to true, this flag indicates if delayed balances should also be returned. Delayed balance objects represent balance that is not yet available for redemption until its active date. Delayed balances being returned will also be split out by their expiration date if there was one, regardless of the balanceExpiration flag. (requires JSON v2)
brandDemographics boolean No false Indicate if the brand specific demographics for a card should be returned.
checkouts boolean No false Indicate if basic information from all historic checkouts for matching cards should be returned. (requires JSON v2)
mailings boolean No false Indicate if historical mailing data should be included in the response data. This functionality is not available by default, please contact Clutch support for access. (requires JSON v2)
emailBounced boolean No false Indicate if the emailBounced property of cards should be returned.
balanceExpirations boolean No false If balances is set to true, this flag indicates if the balances should be broken down by expiration date, showing the expiration date for each block of balances.
checkoutMutations boolean No false Indicate if mutations that happened during historic checkouts should also be returned. This flag is only considered if checkouts is also set to true. NOTE: In case the checkout was performed on a child card, and parent card balances were used, any balance mutation against the parent card will not show up here. See CheckoutLookup or RequestLookup for complete details in these cases. (requires JSON v2)
customData boolean No false Indicate if the third party custom data from the custom third party should be returned.
segments boolean No false Indicate if all segments should be returned that a card is in. This will only be returned for the first card in the search response. It is recommended to only use this return field in combination with a card number filter. This functionality is not available by default, please contact Clutch support for access. (requires JSON v2)
thirdPartyLinks boolean No false Indicate if the third party links data from the third party should be returned.
score boolean No false Indicate if the customer score should be returned if scoring is configured for the current brand and enough data is available for the customer. (requires JSON v2)
balances boolean No false Indicate if balance information should be returned for all results. Will not include delayed balances.
giverCustomer boolean No false Indicate if the giver customer information object should be returned for all results.
alternateCustomer boolean No false Indicate if the alternate customer information object should be returned for all results
pin boolean No false Indicate if the pin from the matching cards should be returned. This functionality is not available by default, please contact Clutch support for access. (requires JSON v2)
recommendationAmount integer No 0.0 Indicate how many (if any) product recommendations should be returned per customer card. This field is not allowed to be set, unless the card number filter is specified. This functionality is not available by default, please contact Clutch support for access. Value should not be smaller than 0. Value should not be larger than 20. (requires JSON v2)
childCards boolean No false Indicate if child cards should be returned if they were attached to any of the returned cards. (requires JSON v2)
coupons boolean No false Indicate if coupon information for matching cards should be returned. Only active coupons will be returned with a limit of 20 (requires JSON v2)
customCardNumber boolean No false Indicate if the custom card number (external card reference) for cards should be returned, if they are present.
isEnrolled boolean No false Indicate if the enrollment status and date per card / primary customer should be returned.
activationDate boolean No false Indicate if the card activation dates should be included for activated cards. This functionality is not available by default, please contact Clutch support for access. (requires JSON v2)
events boolean No false Indicate if all events stored on cards should be returned for the matching card(s).
customer boolean No false Indicate if main customer information should be returned for all results

SubscriptionListInfo

Represents information regarding a brand subscription list.

Parameter Type Required Default Description
name string Yes - Name of the list.
isPublic boolean Yes - Whether the list is public. If not public, the list is private.
uuid string Yes - UUID of the list.

ThirdPartyCardProperties

ThirdParty communication and opt-in settings. This can be used to change the opt-in state per third-party for a certain card.

Parameter Type Required Default Description
thirdParty string Yes - The third party to which this update applies. The third party 'custom’ is used as a catch for third party that that is custom to a brand.. Allowed values are only: gcm, twitter, phone, custom, facebook, vinli, apns, pinterest, instagram, email
optInConfirmed boolean No - Indicates whether the customer has confirmed their subscription, for example by clicking a confirmation link in a welcome email.
payload string No - Optional. Additional custom data, such as a JSON-encoded string with additional custom data. Max length is 128kb. Value should not be longer than 131072 characters.
mobileOperatorId string No - Mobile Operator ID of Consumer, otherwise known as the Network ID. Open Market specific value identifying carrier
optIn boolean No - Whether or not the user wants to opt in for this third party channel as an outbound notification medium.
cause string No - Optional. Indicates the reason that led to the opt in or opt out from this third party. This will only be stored in the opt in or opt out event that may follow from this API call, which means passing this value is ignored unless there are opt in preference changes.
customData string No - Optional. Can contain any custom data, such as a JSON-encoded string with additional custom data. Max length is 128kb. Only available for custom type. Value should not be longer than 131072 characters.
categories Array(ThirdPartyCategory) No - List of categories this card will be (un)subscribed from, requires optIn to be set to true.
optInConfirmationRequired boolean No - Indicate whether this subscription should be confirmed by the customer before it becomes active. Set this to true to comply with Canadian anti-spam laws.
username string No - Optional, currently only used for social media accounts. The username in the scope of the specified third party linked to the selected card number.

ThirdPartyCategory

Subscription status for a specific category of communications.

Parameter Type Required Default Description
optInConfirmed boolean No - Confirmed state, if true the customer has confirmed this opt in and the opt in status will be set to true. This field should only be used for sms categories.
optInPending boolean No - Pending state, if true we are waiting for a customer to confirm this opt in. This field should only be used for sms categories.
name string No - Unique identifier of the category.
optIn boolean Yes false Opt in value, true to opt in, false to opt out.
uuid string No - Unique identifier of the category. This field is required if name is not present.
optInSourceId string No - Opt in source that is triggering this opt in request. Only applies in cases of phone-related opt in requests.

TransferRequest

Used to transfer a card in or out.

Parameter Type Required Default Description
oldCardNumber string No - Only required (or relevant) when the action is transfer in. This value indicates the card number of the card that was previously transferred out and now should have its history copied over to the card indicated by cardNumber.
forcePinValidation boolean No false If set to true, a valid pin is always required for the specified card. This pin always applies to the card specified by cardNumber. Pin validation is not used for the card indicated by oldCardNumber
ignoreHoldBalances boolean No false By default, the transfer out request will fail if the specified card had active balance holds (reservations) on it, as the transfer operation would violate the reservation. If ignoreHoldBalances is set to true, any remaining balance holds will be turned into regular non-reserved balance instead, ready to be transferred out.
owningLocationType string No target Valid options: min, target, source. By default, the owning location of the target card will remain the same. If MIN is selected, the owning location of the card with the earliest signup date is used. If source is chosen the owning location from the source card is used.. Allowed values are only: min, source, target
pin string No - Pin for the specified card, only used if pin validation is needed.
copyCustomCardNumber boolean No false Whether the custom card number should be set on the target card (cardNumber) with the value coming from the card that is being transferred from (oldCardNumber).
overwriteDemographics boolean No - DEPRECATED - use mergeMode instead. Whether demographics should be overwritten on the target card (cardNumber) with data coming from the card that is being transferred from (oldCardNumber). This also includes the enrollment status - if the old customer was enrolled and demographics are being overwritten, the card that is being transferred to will count this registration as the moment when it enrolls. If this is set to false, no demographics data will be transferred from the old card to the new card.
action string Yes - The transfer action that this request should perform. Transfer out means the card indicated by cardNumber will be deactivated and prepared for transfer in to another card. Transfer in means that the card indicated by cardNumber receives all old balances and history from the previously transferred out card. If the action is set to in, oldCardNumber also needs to be specified.. Allowed values are only: zero, in, out
mergeMode string No skip Merge mode used, indicates how the demographics and opt in data from the two transferred cards gets combined. Only read when action is set to IN. Defaults to 'skip’, which does not use any of the demographics or opt in data (including events) from the source card. Alternatively 'combine’ or 'overwrite’ may be used. Combine only copies the opt in preferences or demographics if the data is not present on the target card; Override copies all opt in preferences and demographics from the source card and overwrites overlapping data on the target card. Valid options are: overwrite, skip, combine.. Allowed values are only: skip, overwrite, combine
cardNumber string Yes - The card number to transfer in or out. For transfer in requests, this should be the target card, to which the old balances are transferred.

TransferResponse

Used to transfer a card in or out.

Parameter Type Required Default Description
requestRef string Yes - Unique request reference, can be used for debugging or tracking individual requests / responses.
success boolean Yes false Success flag, true means the request was successfully processed.
errorMessage string No - Error message, can be included if success is false. This field can provide some human-readable insights into the request failure.
errorCode integer No - Error code, will only be included if success is false. See the JSON API documentation for all possible error codes and their meanings.

TriggerCampaignRuleRequest

Request to place a triggerCampaignRule request.

Parameter Type Required Default Description
campaignUUID string Yes - Campaign UUID of the campaign to trigger.
childCardNumber string No - Child card number for which to trigger a campaign rule. This is optional - only specify this if a campaign rule is executing at a child card level.
triggeringUUID string Yes - UUID of this triggering.
campaignRuleUUID string Yes - Campaign rule UUID of the campaign rule to trigger.
cardNumber string Yes - Card number for which to trigger a campaign rule.

TriggerCampaignRuleResponse

Response from triggerCampaignRule calls.

Parameter Type Required Default Description
requestRef string Yes - Unique request reference, can be used for debugging or tracking individual requests / responses.
success boolean Yes false Success flag, true means the request was successfully processed.
errorMessage string No - Error message, can be included if success is false. This field can provide some human-readable insights into the request failure.
errorCode integer No - Error code, will only be included if success is false. See the JSON API documentation for all possible error codes and their meanings.

TriggerCustomCampaignRequest

Request to place a triggerCustomCampaign request.

Parameter Type Required Default Description
customKeyValues Array(CheckoutKeyValue) No - Custom key-value pairs that can optionally be used for custom campaign triggering. This entire array is optional.
cardNumber string Yes - Card number for which to trigger a campaign rule.

TriggerCustomCampaignResponse

Response from triggerCustomCampaign calls.

Parameter Type Required Default Description
requestRef string Yes - Unique request reference, can be used for debugging or tracking individual requests / responses.
success boolean Yes false Success flag, true means the request was successfully processed.
errorMessage string No - Error message, can be included if success is false. This field can provide some human-readable insights into the request failure.
sentNotifications integer No 0.0 Amount of notifications that were sent out, not including direct notifications (those are shown only in the responseMessages property).
errorCode integer No - Error code, will only be included if success is false. See the JSON API documentation for all possible error codes and their meanings.
responseMessages Array(string) No - All messages that can be returned to the customer / end user - only used if campaigns trigger any of these.

TriggerReferRewardsRequest

Request to place a triggerCampaignRule request.

Parameter Type Required Default Description
checkoutTotalSum number Yes - Sum of all checkout totals from referred customers in the previous period
checkoutCount integer Yes 0.0 Amount of checkouts from referred customers in the previous period
cardNumber string Yes - Card number for which to trigger a campaign rule.

TriggerReferRewardsResponse

Response from triggerReferRewards calls.

Parameter Type Required Default Description
requestRef string Yes - Unique request reference, can be used for debugging or tracking individual requests / responses.
success boolean Yes false Success flag, true means the request was successfully processed.
errorMessage string No - Error message, can be included if success is false. This field can provide some human-readable insights into the request failure.
errorCode integer No - Error code, will only be included if success is false. See the JSON API documentation for all possible error codes and their meanings.

UpdateAccountRequest

Used to place UpdateAccount requests, which can be used to update demographics information linked to a card, flag a card / customer as enrolled or update third party settings.

Parameter Type Required Default Description
forcePinValidation boolean No false If set to true, a valid pin is always required for the specified card.
brandDemographics Array(BrandDemographicsProperties) No - Custom Brand Demographics for the specified card.
childCardNumber string No - Child card number, can be specified to modify balance on a child card inside the root card. (requires JSON v2)
newEvents Array(EventRegistration) No - New events that should be added to the card.
customKeyValues Array(CheckoutKeyValue) No - Custom key-value pairs that can optionally be used for custom campaign triggering. This entire array is optional.
thirdPartyUpdates Array(ThirdPartyCardProperties) No - Third party link information for the specified card.
countAsEnrollment boolean No false Whether this transaction should always count as an enrollment for the primary customer, provided this customer is not enrolled yet.
primaryCustomer CustomerUpdates No - Updates to the primary customer.
alternateCustomer CustomerUpdates No - Updates to the alternate customer.
pin string No - Pin for the specified card, only used if pin validation is needed.
customCardNumber string No - A custom reference to this card. This value does not need to be unique across cards and this value can be used to find the card back in a later request. The maximum length is 64 characters.
skipOptInConfirmationEmails boolean No false Skip any potential opt in confirmation emails that this API call would trigger. (requires JSON v2)
cardNumber string Yes - Card number for which to update the linked account.

UpdateAccountResponse

Response from UpdateAccount requests.

Parameter Type Required Default Description
requestRef string Yes - Unique request reference, can be used for debugging or tracking individual requests / responses.
success boolean Yes false Success flag, true means the request was successfully processed.
errorMessage string No - Error message, can be included if success is false. This field can provide some human-readable insights into the request failure.
errorCode integer No - Error code, will only be included if success is false. See the JSON API documentation for all possible error codes and their meanings.

UpdateBalanceRequest

Used to place UpdateBalance requests, these requests can be used to issue or redeem balance, place holds, use holds, or perform accounting adjustments on cards.

Parameter Type Required Default Description
adjustStatus AdjustmentStatusDetails No - If this transaction is an accounting adjustment, this component may be used to adjust the status of the card. Once the status has been adjusted and is no longer an active card, it will no longer be possible to do anything with the card.
forcePinValidation boolean No false If set to true, a valid pin is always required.
customMutationType string No - Define a custom balance mutation type to be associated with this mutation for reporting purposes. This functionality is not available by default, please contact Clutch support for access.
redeemMaxOnOverdraw boolean No false If the amount to redeem is more than what is available on the card, set this flag to true if you want still want to redeem as much as possible. If set to false or left blank, overdrawing will cause an overdrawing request to fail instead.
isReturnRelated boolean No false If this is an issuance, isReturnRelated can be set to true to indicate that the balance being issued is related to the return of merchandise.
amount CardBalanceAmount No - How much to add or subtract from the specified card, should be a positive amount. This is required if the action is issue, redeem or hold.
isAccountingAdjustment boolean No false Set to true if this transaction should be treated as an accounting adjustment
childCardNumber string No - Child card number, can be specified to modify balance on a child card inside the root card. (requires JSON v2)
issuedBalanceActivation string No - Activation date of the issued balance. The balance will not be available until this date, if specified. Format as: yyyy-MM-dd HH:mm:ss, e.g. 2000-01-01 00:00:00 (requires JSON v2) (format: yyyy-MM-dd HH:mm:ss)
redeemFromHoldTransactionId string No - When redeeming, set this field to the hold transaction ID of the held balance you want to redeem from
returnBalances boolean No false Indicates whether balance information for the specified card should be returned
pin string No - Pin for the card, only used if pin validation is needed.
issuedBalanceExpiration string No - Expiration date of the issued balance. Leave this blank for the default behaviour, which is to issue the balance as non-expiring. Format as: yyyy-MM-dd HH:mm:ss, e.g. 2000-01-01 00:00:00 (format: yyyy-MM-dd HH:mm:ss)
releaseHoldRemainder boolean No false When redeeming from a held balance by using a hold transaction ID reference, set this flag to true if the held balance in excess of the redeemed amount should be released again
action string Yes - Whether balance should be issued, redeemed or held from the specified card. Set to adjustOnly if the balance does not need to be modified, but only the status needs to be adjusted. The value adjustOnly is only allowed when isAccountingAdjustment is true.. Allowed values are only: adjustOnly, issue, redeem, hold
cardNumber string Yes - Card of which to modify a balance

UpdateBalanceResponse

Response from UpdateBalance requests.

Parameter Type Required Default Description
balances Array(CardBalance) No - All balances for the specified card, after the update was applied. If balances reach 0, they may be excluded from this list.
requestRef string Yes - Unique request reference, can be used for debugging or tracking individual requests / responses.
convertedAmount number No - If this API call triggered a redemption that performed a currency conversion, this field will contain the amount that was actually redeemed, in the card’s main currency. (requires JSON v2)
success boolean Yes false Success flag, true means the request was successfully processed.
errorMessage string No - Error message, can be included if success is false. This field can provide some human-readable insights into the request failure.
errorCode integer No - Error code, will only be included if success is false. See the JSON API documentation for all possible error codes and their meanings.
didOverdraw boolean No false If a redemption exceeded the amount available on the card, this flag will be set to true
overdrawAmount number No - If didOverdraw is set to true, this field will contain the amount that was overdrawn
transactionId string No - Reference of this transaction, will always be included for successful requests. This is mainly used to reference the transaction that triggered a hold.
cardNumber string No - Card number of which balance was updated. Will always be included for successful requests.

UpdateChannelSubscriptionRequest

Used to place UpdateChannelSubscription requests used to maintain email, phone, etc channel entries.

Parameter Type Required Default Description
customKeyValues Array(ChannelKeyValuesType) No - Optional list of custom brand values that will be stored together with the channel user.
globalOptIn boolean Yes false Required boolean indicating channel is globally opted in or out. False will remove channel from all category lists.
transactionalOptIn boolean No - Optional boolean setting opt in status for transactional channel communications.
doubleOptIn boolean No - Optional boolean indicating channel must be confirmed a second time before use. Distributes branded opt in confirmation message if configured.
channel string Yes - Channel to manage subscription for.. Allowed values are only: phone, email
channelUser string Yes - Email address or phone number. Phone number must be in E164 format for numbers outside the US.
doubleOptInConfirmed boolean No - Optional boolean that may be provided to set the double opt in status to confirmed.
categories Array(ChannelCategoryType) No - Optional subscription status of sub categories.

UpdateChannelSubscriptionResponse

Response from UpdateChannelSubscription requests.

Parameter Type Required Default Description
requestRef string Yes - Unique request reference, can be used for debugging or tracking individual requests / responses.
success boolean Yes false Success flag, true means the request was successfully processed.
errorMessage string No - Error message, can be included if success is false. This field can provide some human-readable insights into the request failure.
errorCode integer No - Error code, will only be included if success is false. See the JSON API documentation for all possible error codes and their meanings.

ValueType

Can be used to indicate a certain value type, being a balanceType and possibly also a balanceCode. Used in requests sent to the server.

Parameter Type Required Default Description
balanceType string Yes - The type of balance that this amount represents. If this is Currency or Custom, the balanceCode is also a required field.. Allowed values are only: Points, Currency, Punches, Custom
balanceCode string No - If the balance type is Currency or Custom, this field indicates the currency code or custom code of the balance. This field will not be included when the balanceType is Points or Punches.

ValueTypeResult

Can be used to indicate a certain value type, being a balanceType and possibly also a balanceCode. Used in responses sent from the server.

Parameter Type Required Default Description
showInTerminal boolean No false Indicates whether the value type should be displayed on the terminal, even if the balance may be zero.
balanceType string Yes - The type of balance that this amount represents. If this is Currency or Custom, the balanceCode is also a required field.. Allowed values are only: Points, Currency, Punches, Custom
balanceCode string No - If the balance type is Currency or Custom, this field indicates the currency code or custom code of the balance. This field will not be included when the balanceType is Points or Punches.
scale integer Yes - The amount of decimals used for this value type. When updating the balance of this value type, only send in amounts that will not cause the balance to have more decimals than the maximum amount allowed amount. If scale is set to 2, updating balance with 0.1 or for instance 0.01 is allowed, but updating balance with 0.001 is not. This value is typically in the range 0-2.
balanceCodeDisplay string No - If the balance type is Custom, this field indicates the code display of the value type. This field will not be included when the balanceType is Currency, Points or Punches.

VoidRequest

Void an old transaction / request.

Parameter Type Required Default Description
requestRef string Yes - The requestRef of the transaction to void. Note: if this references a two-stage locking checkout, it should always reference the checkout complete API call. If the checkout complete call overwrote the payment methods that were used, those will be considered for voiding instead of the ones specified during the checkout setup. Note: if this references a checkout that contained payment methods that redeemed balance, or referenced updateBalance calls as payment methods, those payment methods will be voided as well.
childCardNumber string No - The child card number that was used in the original request. If a child card number was used in the original request, the child card number specified in this request has to match
cardNumber string Yes - The card number that was used in the original request. You can only void calls that were linked to a card number, as anonymous calls or non-writing calls don’t result in anything that can be voided.

VoidResponse

Response from a void request.

Parameter Type Required Default Description
requestRef string Yes - Unique request reference, can be used for debugging or tracking individual requests / responses.
success boolean Yes false Success flag, true means the request was successfully processed.
errorMessage string No - Error message, can be included if success is false. This field can provide some human-readable insights into the request failure.
errorCode integer No - Error code, will only be included if success is false. See the JSON API documentation for all possible error codes and their meanings.

Sandbox

This is a simple sandbox for the JSON API, intended to try out some simple requests and get test responses. You can run your requests both against the stage and production JSON APIs, select the right base URL to determine which environment you are using.

Copy your API Key, API Secret, Brand, test location and test terminal. For a very simple test to see if everything is working, use the API method search and use the test request: {"filters":{}}. Hit the Test it out! button to give it a try.

The response will show up on the right side and should contain "success": true. If it contains "success": false, the errorMessage field might describe what is going on with some more detail. If you cannot figure out why the request is not working and cannot get "success": true to appear, please contact asksupport@clutch.com and show the response that you saw appearing on the right. Especially the "requestRef" value from the response is important and will allow Clutch support to more quickly establish what is going on, this is a unique reference to the request that you placed and will change with every request.

Request

URL used in test request

No URL loaded yet.

Result status code:

No response received yet.

Response:

No request has been sent yet
Base URL:
API Key:
API Secret:
API Method:
Brand:
Location:
Terminal:
Request:

Error Codes

Error code Description
1 Internal server error, contact asksupport@clutch.com to resolve this problem.
2 Card not found, the card number you specified is not found or you do not have access to this card.
3 Duplicate custom request ID, the customRequestId you sent in has previously been used to execute a request for your brand.
4 Concurrent card access, you have multiple concurrent requests that try to modify the same card at the same time. The request could not get access to the card quickly enough before this request timed out.
5 Invalid credentials, the API Key + API Secret + Brand ID combination you used is not valid, or is a set of stage credentials used against a production endpoint or vice versa.
6 Request body is in an incorrect format, the POST data being sent in is either not valid JSON, or does not confirm to the Swagger.io API specification. A required field might be missing, be in the wrong place or be of an incorrect type or format.
7 Card set not found, the card set you tried to use does not exist or you do not have access to it.
8 Transaction not found, the transaction you are referencing is not found or you do not have access to it.
9 Invalid input, one or more input values were not valid. Even though they might be of a correct type and format, they do not allow the request to complete. See the errorMessage for more information.
10 Invalid pin, the card pin you used is not correct.
11 Card not active, the card number you specified belongs to a card that is not active (yet).
12 Balance not found, the balance you referenced in the request could not be found for the card you specified. Does the value type exist and is it set up within the program of the card set of this card? If you are referencing Currency or Custom balance types, is the balanceCode present?
13 Balance limits exceeded, this request cannot complete because it would exceeded one or more balance limits set for the relevant value type for your card.
14 Checkout in progress, this card cannot be used at the moment, because it is currently being used in a locking checkout. In this case, there will also be a "checkoutSetupTransactionId" field in the API response, indicating the transaction ID of the locking checkout setup that is causing this request to fail.
15 Checkout not locked, the checkout-setup you are trying to cancel or complete is not or no longer active. Perhaps the checkout-setup was not set up to be locking, or the lock might have expired.
16 Card set depleted, the allocation could not be completed because the card set no longer contains any available cards.
17 Method not found, the API method you tried to execute was not found.
18 Concurrent channel access. Please try again later.
19 Inconsistent card data, the card data of the associated card is not consistent. Contact Clutch support to track down the problem.
20 Incompatible balances, the indicated balances could not be moved from one card to another, as the target card does not support all balance types.
21 Unresolved holds. When moving balances between cards, this error can be returned if any of the source balance was hold balance, i.e. reserved balance.
22 Coupon set not found.
23 Coupon not found.
24 The specified coupon was not activated / allocated.
25 The coupon reservation state is not valid for the requested operation.
26 Concurrent coupon access, more than one API call is concurrently trying to modify / access the same coupon. Please try again in a little while.
27 Invalid coupons, one or more of the specified coupons were not valid.
28 Concurrent request access on the specified request, please try again later.
29 The specified request was not found.
30 The specified equest has already been voided.
31 The transaction type of the specified request is not valid for this operation.
32 Request headers are in incorrect format.