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.
- Clutch Portal, allows you to configure almost everything for your brand. New features are continuously being added, but if you find something that you cannot configure through the Portal, our support team will be able to assist you.
- Virtual Terminal, this is a simplified online 'Point of Sale’ you can use to process transactions.
- Member Portal, depending on your brand setup, we can set up a member portal for you. In the member portal your customers can sign up with their card number and change their own demographics or link up with third parties, for instance linking their Twitter account to a card.
- JSON API, the actual API that you can call to programmatically execute transactions.
- Older APIs, not recommended to be used in new applications. Once you start using the JSON API, you should not be using the older APIs to access your brand’s data anymore.
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:
- Stage portal: https://stage-portal.clutch.com
- Production portal: https://portal.clutch.com
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:
- Sign in to the Portal (stage or production, depending on where you want to use the API keys)
- In the left navigation, go to Admin > API Credentials
- In the top-right corner, press the green button for “New API Key”
- 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.
- 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:
- Your API Key / Secret for stage or for production
- Your brand ID
- Your test location ID
- 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:
- Sign in to the Portal (stage or production, depending on where you want to test out your requests)
- In the left navigation, go to Documentation > JSON API Sandbox.
- Enter you API Key and Secret and hit the button.
- 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
- Groups
- Portal logins (optionally restricted to location)
- Locations
- Terminals
- Employees
- Programs
- Value types
- Card sets
- Cards
- Card balances
- Customer demographics
- Coupon sets
- Coupons (unique at brand level)
- Campaigns
- Campaign rules
- Campaign rule conditions
- Campaign rule results
- Customer segment definitions
- API credentials
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:
- Currency, in which case the balanceCode indicates which currency code the value type refers to
- Custom, in which case the balanceCode indicates which custom balance the value type refers to
- Points, no balanceCode is specified
- Punches, no balanceCode is specified
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:
- For stage: https://api-stage.clutch.com/merchant/
- For production: https://api.clutch.com/merchant/
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. By default, every API request must have at least 4 headers for authentication and identification:
- Header
Authorization
, for HTTP Basic authentication using your API key and API secret as username and password. - Header
Brand
, for your brand ID. This is needed for authentication, as your API key exists within your brand. - Header
Location
, for your location ID. This is used to identify where the request is coming from. - 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.
Authentication with Digital Signature
Generating an RSA-2048 key pair with openssl on Linux
# Generate a private key
openssl genrsa -out your-private-key.pem 2048
# Generate a public key
openssl rsa -in your-private-key.pem -outform PEM -pubout -out your-public-key.pem
Pre-signed content construction (signature version 1)
String preSignedContent = brandId + "\n" +
locationId + "\n" +
terminalId + "\n" +
signatureDateTimeStr + "\n" +
(employee == null ? "" : employee) + "\n" +
(externalTransactionId == null ? "" : externalTransactionId) + "\n" +
(customRequestId == null ? "" : customRequestId) + "\n" +
(note == null ? "" : note) + "\n" +
postBody;
Creating a signature from pre-signed content
//import java.nio.charset.StandardCharsets;
//import java.security.PrivateKey;
//import java.security.Signature;
//import java.util.Base64;
Signature privateSignature = Signature.getInstance("SHA256withRSA");
privateSignature.initSign(privateKey);
privateSignature.update(preSignedContent.getBytes(StandardCharsets.UTF_8));
byte[] signatureBytes = privateSignature.sign();
Strig signature = Base64.getEncoder().encodeToString(signatureBytes);
Instead of the Authorization
header using HTTP Basic Authentication, it’s also possible to use a digital signature, using an RSA-2048 key pair and SHA256 with RSA.
To start using this method, first generate an RSA-2048 key pair. Keep your private key to yourself and send the public key as a PEM file to Clutch customer support. You will receive the API Key identifier that is assigned to your key pair.
The public key file should be in plain text and should start with -----BEGIN PUBLIC KEY-----
. Each line should contain at most 64 characters (not including linebreaks) of base64 encoded data containing the modulus and exponent of your public key in X.509 SubjectPublicKeyInfo format. Note that this is different from an X.509 certificate. You can generate a public key in this format with OpenSSL from your private key with openssl rsa -in your-private-key.pem -outform PEM -pubout -out your-public-key.pem
. Also see the full example in the right column.
To sign a request to the JSON API, do not send in the Authorization
header, but instead add the following headers:
- Header
SignatureVersion
, set this to1
. This defines the format for the content being signed. This is currently always 1. - Header
SignatureDateTime
, set this to the current date+time when placing the request in UTC, e.g. ‘2019-12-31 23:59:59’. Format isyyyy-MM-dd HH:mm:ss
. Make sure your clock is in sync using an NTP service or similar, a maximum drift of 15 minutes is allowed. - Header
ApiKey
, set this to the API Key identifier for the key pair you’re using to sign the request. - Header
Signature
, specify the request signature here, base64 encoded.
To generate your signature, first construct the pre-signed content with the following items (one item per line):
- Brand ID
- Location ID
- Terminal ID
- Signature date+time (e.g.
2019-12-31 23:59:59
), in UTC timezone - Employee ID (or empty string if not specified)
- External transaction ID (or empty string if not specified)
- Custom request ID (or empty string if not specified)
- Note header value (or empty string if not specified)
- Request JSON (can be multiple lines)
Use a single carriage return (0x0D) to split lines and don’t add any whitespaces that aren’t present in the actual headers or POST data.
With the pre-signed content and your private key, you can sign your request. Use a SHA256withRSA algorithm to create the signature with PKCS#1 v1.5, also known as RSASSA-PKCS1-v1_5. The signature header should be base64 encoded.
Additional headers
Besides the headers for authentication, you can optionally also send in the following headers:
- Header
Employee
, for your employee ID. This can be sent in to identify which employee should be tagged on the request. - Header
externalTransactionId
, custom request identifier for logging. See Listing Requests. - Header
customRequestId
, custom request deduplication identifier. See Idempotence. - 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:
- New request parameters that are added will always be optional
- Existing 'required’ response data is never removed
- Existing requests that do not include undocumented request fields will always continue to work, regardless of API changes
As a result, new API features will consist of:
- New API methods
- New optional request parameters on existing API request models
- New optional or required response parameters on existing API response models
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:
- Place the request
- 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 - 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.
- Repeat the process, at most 5-10 times per request.
Errors you could retry:
- Any network connectivity issue where no response is received
- Error code 1, i.e. Internal server errors in the JSON API (not necessarily HTTP status code 500, but
"errorCode": 1
coming back in the JSON response). - Error code 4 (Concurrent card access).
- Error code 14 (Checkout in progress).
Employee identification
If you also want to specify which employee is executing a request, you can add the headers:
- Header
employee
, the employee ID - Header
employeePassword
, the password / passcode for the specified employee
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:
- 0 or more conditions
- 0 or more results
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:
- Checkout-triggered, when checkout API calls are placed.
- Account Update-triggered, when updateAccount API calls are placed.
- Date-triggered, when a certain event (to be specified) occurs, the campaign will automatically fire early in the morning. Can be useful to send customers a 'Happy Birthday’ email for instance.
- Social media response-triggered, when a social media event occurs, you can automate a response or balance issuance.
- Post processing-triggered, at the end of any API call.
When you set up a date-triggered campaign rule, there are usually 3 things to configure:
- 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.
- 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’.
- 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
Adding Personal Offers
{
"cardNumber": "ABC",
"offer": {
"discountType": "percentageDiscount",
"percentageDiscount": 10,
"skus": [
{
"sku": "SKU-123",
"includeChildProducts": true
}
],
"customId": 11223344,
"activationDate": "2029-12-21 23:59:59",
"expirationDate": "2030-01-01 23:59:59"
}
}
Example response:
{
"success": true,
"requestRef": "b5889a0f-3426-4381-84eb-6c2b7d79bdb9"
}
To add a personal offer to a card, use an AddPersonalOfferRequest object, the response will be an AddPersonalOfferResponse object.
In the request, you can choose one of the different discount types, for instance ‘percentageDiscount’.
You also have to specify the 'skus’ property for a new offer, to define which products get the discount. The offer will only be applied if all of these products are present in a checkout and can receive a discount, meaning those units of the product haven’t received another discount from another offer yet.
The same unit of quantity of a product can only receive up to 1 offer in a single checkout. All offers will be processed in the order in which they were added to the card, first added being processed first.
You can also specify 'qualifyingProducts’ on an offer. The offer will only execute if those products are present in the checkout. For that property, it doesn’t matter if those qualifying products already received a discount from another offer or not.
All offers get executed before campaign engine logic fires.
Offers can have an activation date in the future, if they should not be available immediately. All offers must have an expiration date on them, of at most one year into the future.
An offer can only match once per checkout. Optionally, you can specify the amount of times an offer can be used, meaning the offer can then be used in multiple checkouts, but still only once per checkout at most.
By default, all skus and qualifying products are considered to have a quantity of 1. If you want to discount more than 1 unit of quantity of a product, you can add it to the skus property multiple times. In this case, the offer will still only match if the quantity of that SKU in the checkout is at least as much as the amount of that SKU specified in the skus property.
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
- You have a webshop selling giftcards and want to issue a new virtual giftcard.
- You want to select a new random card number and print it on something afterwards.
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
- You have a stack of physical 'inventory’ cards in your brick and mortar store.
- You have a webshop selling giftcards and have to mail out pre-produced physical cards when they are ordered.
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:
- Standalone checkouts
- Two-stage checkouts
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
- If your brand does not have any Campaigns set up that give discounts, use a standalone checkout. First process the checkout and once payment is complete, place the API call.
When not to use
- If you have Campaigns set up to calculate discounts, don’t use standalone checkouts. You will first need to place an API call to figure out how much discount to give, then process the payment for that checkout and after that, place a second API call to indicate that payment is complete and the checkout can be finalized.
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
- If you would like to know the balance mutations that would happen for a checkout before actually finalizing the checkout.
- If you have Campaigns set up that give a discount, but this discount is only based on the items being purchased or the current checkout total.
When not to use
- If you have Campaigns set up that give a discount based on anything other than the current cart content or checkout total. E.g. If the discount is based on the card’s balances, previous visits or purchases, customer enrollment status, customer birthday, previous amount spent, all-time total amount purchased of a certain product, do not use a non-locking two-stage checkout. In these cases, use a Locking two-stage checkout instead.
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
- If you have Campaigns that give a discount based on anything on the card that could change, such as balances, enrollment status or card settings or fields. If you use discounts based on something other than the items being purchased or the current checkout total, this is the most optimal approach.
- If you want to know the balance mutations of all campaigns with absolute certainty before processing a checkout payment.
When not to use
- If you don’t want to 'lock’ the card during the payment process.
- If a checkout is initiated in a webstore and you don’t want to finalize the checkout / give the points until the items are shipped, you could potentially be locking the card for a very long time. If possible you could use a non-locking two-stage checkout, otherwise contact Clutch for a custom solution that works best in your situation.
- If you don’t have any campaigns set up that calculate discounts, or only calculate discounts based on current cart contents or current checkout total, a locking checkout is likely overcomplicated for your situation. Perhaps consider a non-locking two-stage checkout.
- For anonymous checkouts.
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:
- You have a campaign rule that gives 1 point per $1 spent.
- You have another campaign rule that turns 100 points into 5 'dollars’ of cashback balance (custom.cashback).
- You have another campaign rule that gives $5 discount on any purchased hat.
- Because there are no discounts based on the card state, a two-stage non-locking checkout can be used.
- Every checkout setup API call is configured to return balances.
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 - Standardized options
A checkout response can contain standardized campaign choices. In this case, there will be a response structure in the availableOptions
field in a checkout response containing CampaignOption model. This will only be returned in a checkout setup call.
In the returned options, there will be a number of fields:
- Choice group ID, if there are multiple options in the response, this determines grouping
- Option ID, a unique identifier for this option
- Option display value, a display value for this option that can be shown to the customer
- Max selected options count
If multiple options are returned with the same choice group ID, the customer can choose zero or more options from that group. The maximum amount that can be selected at once in such a group is determined by the smallest value of maxSelectedOptions
for all returned availableOptions
.
To send in a choice, specify campaignChoices
in the checkout request object. Each choice should include the choiceGroupId
and the selected optionId
.
In case of locking two-stage checkouts, it is recommended to first call non-locking checkout setup to see which options are available and place a subsequent checkout setup call with the customer’s choices in that request. Campaign choices can be sent in during a locking checkout setup or a standalone checkout complete call, but not during a locking checkout complete call.
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:
- Place a checkout setup API call, receive customer messages back.
- Show messages to the customer, customer might add another product to the checkout.
- Cancel the first checkout and place a new checkout setup call.
- 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:
- 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.
- 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.
The cardNumber used in the linked requestRef MUST be the same as the cardNumber in the checkout.
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.
Allocating a new coupon
Example coupon create + allocate request:
{
"cardNumber": "your-card-123",
"couponSetId": "your-coupon-set-id",
"promotionId": "your-promotion-id",
"couponId": "new-coupon-123",
"createIfNew": true,
"newPin": "PIN1234"
}
You can allocate a coupon by either specifying the coupon set and getting a random inventory coupon, or by creating a new coupon on the spot.
If you have not created any inventory coupons for your coupon set, you can simply create and allocate a new coupon with one API call to allocateCoupon
. Please note that the coupon ID must be unique within your brand.
If you want to use your coupon in campaigns or issue any balances to it, make sure you allocate the coupon and specify a cardNumber
to attach to the coupon.
When allocating a coupon, you can optionally specify the newPin
field. You can retrieve this PIN from the coupon details call later on.
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,
"pin": "PIN1234"
}
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.
Coupon Balances
Once you have a coupon that is attached to a card, you can also issue balance specifically to that coupon. This balance will be separate from any other balance on the card and can have its own balance holds (reservations), hold redemptions, hold releases and regular issuances / redemptions.
The balances that are attached to a coupon will not be combined or show up as regular card balance. If you issue 10 Points to a card and also 5 Points to a specific coupon on that card, a regular redemption cannot exceed 10 Points.
Issuing coupon balance
Request to issue coupon balance:
{
"cardNumber": "your-card-123",
"couponId": "your-coupon-123",
"action": "issue",
"amount": {
"balanceType": "Points",
"amount": 100
}
}
Request to redeem coupon balance:
{
"cardNumber": "your-card-123",
"couponId": "your-coupon-123",
"action": "redeem",
"amount": {
"balanceType": "Points",
"amount": 100
}
}
To issue coupon balance, call updateBalance and specify a cardNumber
, but also a couponId
.
Everything else is identical to regular updateBalance
API calls.
Looking up coupon balances
Sample search response:
{
...
"cards": [
{
"cardNumber": "your-card-123",
"balances": [
{
"amount": 100,
"balanceType": "Points",
"scale": 0,
"balanceBucket": {
"couponId": "your-coupon-123"
}
}
...
]
}
...
]
}
To see how much balance is available on a card, you can use the same search
API call you would use to see regular card balances.
The resulting CardBalance
objects will have a field balanceBucket
for any balances that are coupon-specific.
This object has a couponId
field to indicate which coupon the balance belongs to.
Looking up original issuance amount
Request to look up coupon details:
{
"cardNumber": "your-card-123",
"couponId": "your-coupon-123",
"action": "details"
}
Sample couponDetails response:
{
"success": true,
"requestRef": "daad8e25-f4fd-4fde-86b6-16a1c2456e42",
"isAllocated": true,
"isUsed": false,
"isDisabled": false,
"firstIssuanceAmount": 100
}
To see the original amount that was issued to a coupon, place an API call to couponDetails
. You will get back a field firstIssuanceAmount
in case the coupon has any balance issuances to it.
If you issue balances in more than one balance type, you will not get back the firstIssuanceAmount
field.
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:
- Root event type (e.g.
CUSTOM
) - Category ID (highest identifier)
- Specific ID (optional lower level identifier)
- Optional descriptive name
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:
- updateAccount to manually add events
- campaigns have a logEvent result to log custom events
- mailings will create events (sent, received, read, clicked, bounced, etc)
- opt ins and opt outs automatically create events
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:
- Currency, in which case the
"balanceCode"
field indicates which currency it is - Custom, in which case the
"balanceCode"
field indicates which custom value type it is - Points, no extra fields will be present
- Punches, no extra fields will be present
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:
- Twitter, you can link a Twitter username. It is recommended to make sure the Twitter account is following your brand’s Twitter account before linking it to a card. This way, you are ensured that direct messages or tweets will actually arrive when they are sent out.
- Email, for the third party 'email’, you can only set the
"optIn"
setting in the thirdPartyUpdates field. The actual email address can be set using the email field on the primaryCustomer field. - Custom, used to store any custom data. Use the field customData, see Custom card data for more information.
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.
Push Notifications
Push notifications can be triggered by Clutch campaigns through either a custom webhook / callback, or through the built-in Clutch push notification system.
To use the Clutch push notification system, please contact customer service first to configure your brand.
Once your brand is configured, you can specify an APNS and/or a ‘GCM’ (currently FCM / Firebase) device token to use for a single card.
Connecting from an app
Call to updateAccount to link an apns device token
{
"cardNumber": "abcd1234",
"thirdPartyUpdates": [
{
"thirdParty": "apns",
"username": "the-apns-device-token-goes-here"
}
]
}
In your app, make sure the user is logged in and connected to a Clutch card through a middleware application. This can be either the Clutch Mobile API (not covered in this documentation page), or a custom middleware application that hits the JSON API directly. The Clutch Mobile API acts as middleware for the JSON API and will also end up registering the APNS / GCM/FCM tokens through the JSON API in the same way.
Once the user is logged in and linked with a Clutch card, your app can request a device token.
On iOS / Objective-C, this can be done with a call to registerForRemoteNotificationTypes
,
listening for a callback to didRegisterForRemoteNotificationsWithDeviceToken
,
which will give you the device token.
On Android, obtain the FCM (Firebase messaging) registration token. Note - this will be referred to in the Clutch JSON API as the 'GCM’ device token.
Depending on the platform you are using for you mobile application, the exact method of obtaining a device token will vary.
Once you have obtained a device token, send this to your middleware, which should then place a call to the JSON API updateAccount method.
Sending push notifications
Configure a campaign to send a notification result of type pushnotification
and subtype either apns
or gcm
.
In the notification result, you can specify the subject and content/message.
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:
- Issue balance, add some balance
- Redeem balance, remove some balance
- Hold balance, reserve some balance
- Update a hold reservation
- Deactive all balances by adjusting the card status
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:
- Any return-related balance is redeemed before non-return-related balance. This means store credit is always used first.
- 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:
- Log the return for reporting purposes.
- Remove custom events created by campaigns during the original checkout.
- Flag coupons used in the original checkout as unused again.
- Disable coupons that were issued during the original checkout.
- Verify that the return total and list of returned SKUs does not exceed the original checkout’s contents.
- Simulate the return first, to make sure this is possible
Failure handling
By default, a return request will fail if:
- Coupons issued by the original checkout were already used.
- The total being returned, plus potential previous returns for the same checkout, exceeds the orginal checkout total after discounts.
- The quantity of SKUs being returned, plus potential previous returns for the same checkout, exceeds the quantity for that SKU present in the original checkout.
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:
- cardNumber, the main Clutch card number. This is a unique number.
- customCardNumber, your own customCardNumber. Multiple cards can share the same customCardNumber.
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": {"cardNumber": "1234"},
"includeInactive": true,
"returnFields": {
"balances": true,
"brandDemographics": true,
"decorateCustomValues": true,
"customer": true,
"alternateCustomer": true,
"giverCustomer": true,
"isEnrolled": true,
"customData": true,
"customCardNumber": true
}
}
Response with all fields set:
{
"cards": [
{
"cardNumber": "1234",
"cardSetId": "abc",
"balances": [
{
"amount": 100,
"balanceType": "Currency",
"balanceCode": "USD",
"scale": 2,
"isHold": false
},
{
"amount": 25,
"balanceType": "Points",
"scale": 0
}
],
"customer": {
"firstName": "John",
"lastName": "Johnson",
"email": "john.johnson@clutch.com"
},
"alternateCustomer": {},
"isEnrolled": false,
"enrollmentDate": "2023-05-24",
"brandDemographics": "{\"favoriteColor\":\"Blue\"}",
"cardStatus": "Activated",
"customCardNumber": "XYZ_987",
"sequenceNr": 3041
}
],
"usedCache": false,
"success": true,
"requestRef": "0a6bf2c9-d240-40ad-wxyz-e62d8fdd2236"
}
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:
- Currency, the balanceCode now indicates the currency code (e.g. USD)
- Custom, the balanceCode now indicates your custom associated value type code
- Points, no balanceCode is used. Usually used in campaigns where every Dollar spent earns you a certain amount of Points.
- Punches, no balanceCode is used. Usually used in campaigns where you get one Punch per checkout.
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:
- The specified card could not be found, the request will be successful but 0 cards will be returned.
- More than one card matches the search filters. Error code 9 (invalid input) will be returned. A pin can only be validated for one card, if multiple cards match the API will not try to match the pin to all cards for security reasons.
- One card matches the search filters, but the pin is incorrect. Error code 10 (invalid pin) will be returned.
- One card matches the search filters and the pin is correct. The request will be successful and 1 card is returned.
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:
- updateAccount
- updateBalance
- checkout
- voidTransaction
- returnMerchandise
In addition, you can get child card information back in:
- search
- cardHistory
- checkoutLookup
- requestLookup
Child cards do not have all features that regular cards do:
- They do not have card PIN support
- They do not belong to a program or card set themselves
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.
AddPersonalOfferRequest
Request to add a personal offer to a card, for later use during checkouts.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
offer | PersonalOffer | Yes | - | The personal offer to add |
cardNumber | string | Yes | - | Card number that receives this personal offer |
AddPersonalOfferResponse
Response from addPersonalOffer 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. |
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. NOTE: The ‘Transfer’ status can only be used on child cards! Child cards can only transition into 'Transfer’ or 'Suspended’.. Allowed values are only: Lost, Closed, Transfer, Expired, Suspended, Stolen |
AllocateChildCardRequest
Request to allocate a child card, used to place allocateChildCard requests.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
childCardNumber | string | Yes | - | 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 36 characters (inclusive), and cannot contain commas. Value should not be shorter than 3 characters if it’s specified. Value should not be longer than 36 characters if it’s specified. |
cardNumber | string | Yes | - | 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) |
failOnMultipleCoupons | boolean | No | true | Flag to determine if the request should fail if the card already has a coupon for the given promotion. |
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. |
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. |
newPin | string | No | - | In case createIfNew is set to true and the coupon is related to a cardNumber, and a new coupon is being created, this field can be used to specify the PIN for this newly created coupon. Value should not be longer than 20 characters if it’s specified. |
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) |
customRequestDate | string | No | - | Custom request date, used to set an alternative processing date on this allocate request. Must be turned on via brand setting. (format: yyyy-MM-dd HH:mm:ss) |
brandDemographics | Array(BrandDemographicsProperties) | No | - | Custom Brand Demographics for the specified card. These fields will be populated immediately after allocation. (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. If specified, should be at least 4 characters long and at most 100 characters long. |
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. |
BalanceBucket
Reference to a bucket of balance, e.g. balance for a given coupon will have a reference BalanceBucket object to indicate which coupon it belongs to.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
subtrackConversionRate | integer | No | - | Optional, in case this balance bucket relates to a punch subtrack, this is the conversion rate of that subtrack |
subtrackDollarBased | boolean | No | - | Optional, in case this balance bucket relates to a punch subtrack, this is a flag that is true for dollar-based subtracks and false for quantity-based subtracks |
subtrackDisplayName | string | No | - | Optional, in case this balance bucket relates to a punch subtrack, this is the display name of that subtrack |
couponId | string | No | - | Optional, in case this balance bucket belongs to a coupon, this is the coupon ID |
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. Only compatible with fields that are of a list type. (requires JSON v2) |
value | string | No | - | Optional, may not be provided at the same time as 'values’. Value to set the field value to, when mode is set to 'overwrite’, passing a null value will unset the property. If field contains a date, the value must be in the yyyy-MM-dd format. Only compatible with fields that are not of a list type. |
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. |
childCard | boolean | No | - | Flag, will be true if this mutation happened against a child card. Null or false indicates the mutation happened against the parent card |
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. |
skuSequenceId | integer | No | - | If the related SKU is set, this field indicates the original sequence number of the product that was discounted. |
offerIndex | integer | No | - | In case of discounts that were triggered by personalized offers, this will be the offer index of the offer that triggered this discount |
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) |
CampaignChoice
Representation of a choice that a user made for execution of a certain campaign rule.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
choiceGroupId | string | No | - | Choice group ID for this option. |
optionId | string | No | - | Selected option. If a user wants to select multiple different options, this should be represented by multiple CampaignChoice objects with identical choiceGroupIds but different optionId values. |
CampaignOption
A campaign execution option that is available for a user to pick.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
maxSelectedOptions | integer | No | 0.0 | Maximum amount of options in the current choice group that can be selected. If more options in the same choice group are sent in than this number, this option will not be executed. |
choiceGroupId | string | No | - | ID of the group to which this choice option belongs. |
optionId | string | No | - | ID of this unique option |
selected | boolean | No | false | Flag that indicates whether this campaign option was marked as selected in the checkout request. |
optionDisplayValue | string | No | - | A display value for this specific option, in the default language of the current brand |
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 |
---|---|---|---|---|
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) |
score | CardScore | No | - | Customer score (requires JSON v2) |
metaData | CardMetaData | No | - | Additional card meta data, only returned if metaData was requested in the search return fields object. (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) |
sequenceNr | integer | No | - | Sequence NR for this card, used for multi-issuance. |
childCards | Array(Card) | No | - | Child cards that are attached to this card. Even if you specified any child card filters on this search request, the childCards structure here will not be filtered and contain all child cards attached to the matching parent card. (requires JSON v2) |
coupons | Array(CardCoupon) | No | - | List of active coupons for this card. Max of 20 coupons returned. (requires JSON v2) |
personalOffers | Array(CardPersonalOffer) | No | - | Personal offers that are available for this card, only returned if this was requested in the search return fields object. Will not include expired offers, but will include offers that are not yet available. NOTE: Will only return up to 100 offers. (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. |
isEnrolled | boolean | No | - | Whether the primary customer linked to this card is flagged as enrolled into the loyalty program. |
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. |
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. |
enrolledPrograms | Array(EnrolledProgram) | No | - | Programs that this card is enrolled in, this is excluding the main loyalty program if applicable. (requires JSON v2) |
surveyResponses | Array(SurveyResponse) | No | - | Survey response data, only returned if this was requested in the search return fields object. (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. |
mmsBounced | boolean | No | - | Whether a COMMUNICATION_FAILED event was logged on the card that was not followed by an MMS_FAILURE_CLEARED event. |
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. |
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. |
customer | Customer | No | - | The primary customer linked to this card. |
statistics | CardStatistics | No | - | Card purchase statistics, only returned if this was requested in the search return fields object. Returns mostShoppedLocationId, mostSpentLocationId, and lastShoppedLocation. (requires JSON v2) |
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) |
balanceBucket | BalanceBucket | No | - | Optional, this will typically be null. If this is specified, the balance belongs to a specific 'bucket’ on the card, e.g. it’s balance that belongs to a certain coupon on the card. |
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) |
couponValueType | string | No | - | Value type of coupon. This does not related to any coupon balances, but just to the couponValue! |
issuedDate | string | No | - | Date when this coupon was issued. (format: yyyy-MM-dd HH:mm:ss) |
firstIssuanceAmount | number | No | - | Optional, if this is a coupon attached to a card and the card had any issuances for balance specifically for this coupon, this is the amount of balance that was issued during the first issuance to the coupon. |
description | string | No | - | Description of coupon. |
couponId | string | No | - | Coupon ID. |
promotionId | string | No | - | Promotion ID |
couponValue | number | No | - | Value of coupon. Note - this is not the coupon balance! For coupon balances, see the balance responses, with objects that contain a balance reference to the coupon ID. |
expirationDate | string | No | - | Date when this coupon expires. (format: yyyy-MM-dd HH:mm:ss) |
CardEntryMethod
Card entry method, may be provided for receipt functionality.
Parameter | Type | Required | Default | Description |
---|
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 |
---|---|---|---|---|
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) |
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) |
couponId | string | No | - | Optional, defaults to undefined. If defined, only transactions with specific coupon balance mutations will be included. (requires JSON v2) |
includeMainBalanceUpdate | boolean | No | false | Optional, defaults to false. If true, the main balance update, the merchant name and checkout total after discounts for the transactions are included. |
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) |
includeLifeCycleStatistics | boolean | No | false | Optional, defaults to false. If true, include stats must also be set to true. If defined, returns daysUntilAtRisk and daysUntilChurned. If a child card number was specified, these statistics will only apply to the selected child card. (requires JSON v2) |
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) |
includeStats | boolean | No | false | Optional, defaults to false. If true, various statistics from the customer will be included. If a child card number was specified, these statistics will only apply to the selected child card. (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) |
includeLocationNames | boolean | No | false | Optional, defaults to false. If true, location names will be included for the returned transactions. (requires JSON v2) |
includeSuspicionScoreStatistics | boolean | No | false | Optional, defaults to false. If true, include stats must also be set to true. If defined, returns suspicion score. If a child card number was specified, these statistics will only apply to the selected child card. (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. |
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) |
stats | CustomerStats | No | - | Only included if includeStats = true in the request. Will include statistical information about the customer. (requires JSON v2) |
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. |
lifeCycleStats | LifeCycleStats | No | - | Only included if includeLifeCycleStats = true in the request. Will include information about the customer’s life cycle status. (requires JSON v2) |
suspicionScoreStats | SuspicionStats | No | - | Only included if includeSuspicionScoreStatistics = true in the request. Will include how suspicious purchase activity on this card is, from 1 to 100. (requires JSON v2) |
CardHolderVerificationType
Card holder verification method, may be provided for receipt functionality.
Parameter | Type | Required | Default | Description |
---|
CardMetaData
Meta data for a single card object
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
cardCurrency | string | No | - | Base currency (currency code) assigned to the card |
programType | string | Yes | - | Program type of the program to which this card’s card set belongs. |
programName | string | Yes | - | Name of the program to which this card’s card set belongs. |
owningLocationName | string | No | - | Name of the owning location that’s associated to this card. |
baseCurrency | string | No | - | Base currency (currency code) of the program to which this card’s card set belongs. |
CardPersonalOffer
Representation of an offer that is available to a card
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
createdDate | string | No | - | Date when this offer was added to the card. (format: yyyy-MM-dd HH:mm:ss) |
availableDate | string | No | - | If set, this is the date when the offer becomes or became available. (format: yyyy-MM-dd HH:mm:ss) |
customId | integer | No | - | Custom ID, in case this personal offer was added through an API call that specified the custom ID. |
expirationDate | string | No | - | If set, this is the date when the offer expires. (format: yyyy-MM-dd HH:mm:ss) |
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. |
CardStatistics
Representation of card purchase statistics.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
mostSpentLocationId | string | No | - | External location id of the location with the most amount spent |
lastShoppedLocationId | string | No | - | External location id of the last location customer shopped at with the card |
mostShoppedLocationId | string | No | - | External location id of the location with the most checkouts |
CardSubscription
Compact representation of a subscription on a card.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
tier | string | No | - | The subscription’s tier. |
sourceSystem | string | No | - | Source system of the subscription. |
name | string | No | - | Name of the subscription. |
systemType | string | No | - | System type of the subscription. |
subscriptionStatus | string | No | - | The current status of the subscription.. Allowed values are only: Active, Inactive |
assignmentStartDate | string | No | - | Date the subscription starts. (format: yyyy-MM-dd HH:mm:ss) |
externalId | string | No | - | External id, which can overlap universities. |
subType | string | No | - | Sub type of the subscription. |
assignmentDate | string | No | - | Date the subscription was assigned to the card. (format: yyyy-MM-dd HH:mm:ss) |
assignmentEndDate | string | No | - | Date the subscription ends. (format: yyyy-MM-dd HH:mm:ss) |
subscriptionId | string | No | - | Subscription id, unique for each subscription. |
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 |
---|---|---|---|---|
revenueCenter | string | No | - | The revenue center assigned to the checkout. These are pre-configured for each brand. (requires JSON v2) |
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. |
checkoutShippingTotal | number | No | - | Total shipping amount paid with the checkout. (requires JSON v2) |
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. |
employeeId | string | No | - | Employee ID (external) that was sent in for this transaction. 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) |
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. |
checkoutTaxTotal | number | No | - | Total tax applied to the checkout. (requires JSON v2) |
requestRef | string | Yes | - | Unique request reference, can be used for debugging or tracking individual requests / responses. |
checkoutDate | string | No | - | Date/time when this checkout was executed. (format: yyyy-MM-dd HH:mm:ss) |
orderMode | string | No | - | The name of the order mode assigned to the checkout. If no order mode is sent in at the checkout level, this will return the order mode . (requires JSON v2) |
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 |
---|---|---|---|---|
skuName | string | No | - | SKU Name to describe the SKU. This field should never be specified in a request, but is only intended for CheckoutLookup responses that return this object. |
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. |
note | string | No | - | Optional, an extra note to add to this SKU. Max length is 32. This field can’t be used in reporting or segmentation, but can contain custom information for future checkout lookups. Value should not be longer than 32 characters if it’s specified. |
amountPurchased | number | No | 1.0 | Product quantity that was purchased. Should be a positive number, larger than or equal to 0. |
orderMode | integer | No | - | Optional order mode flag on a line item level. This can be used to override an order mode that is specified on the checkout itself. (requires JSON v2) |
parentSequenceId | integer | No | - | Optional sequence id of the parent of this checkout product. Required to be set, along with the parent’s sequenceId property, for checkout products that have a nesting. |
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. |
sequenceId | integer | No | 0.0 | Optional one based index that identifies the position of this product in the list of line items. When left blank it will be populated by the API based on the input order and may later be communicated back when a specific line item is discounted. It is recommended to use the same value for checkouts and returns of a specific product. |
properties | Array(CheckoutProductProperty) | No | - | Optional, list of custom properties for this SKU. Only use this if your brand uses a custom SKU property model. (requires JSON v2) |
CheckoutProductProperty
Representation of a single property of a single line item in a checkout.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
dateValue | string | No | - | If the property is a date, this is the date value that goes with the specified property. (format: yyyy-MM-dd HH:mm:ss) |
property | string | Yes | - | Property key, this is the internal name from the custom SKU property model. Specify one of the different values depending on the property’s data type. |
choiceValue | string | No | - | If the property is a choice, this is the string value of the choice that goes with the specified property. |
longValue | integer | No | - | If the property is a number, this is the numerical value that goes with the specified property. |
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 |
---|---|---|---|---|
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. |
revenueCenter | integer | No | - | Revenue center, can optionally be specified on the checkout for reporting purposes. (requires JSON v2) |
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. |
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. |
merchantName | string | No | - | Optional, the merchant name to associate with this transaction, in case there is no location data available. In case of two stage checkouts that have a value for this field, this should be sent in with the checkout complete call as well. Value should not be longer than 64 characters if it’s specified. (requires JSON v2) |
returnBalanceMutations | boolean | No | false | Set to true to obtain a list of detailed balance mutation information for all balance updates and discounts. |
customLoggingDate | string | No | - | Custom logging date, used to set an alternative logging date on this checkout request that may be up to one year in the past. This will not impact balance mutations, only the date on the transaction and purchase object will be altered. (format: yyyy-MM-dd HH:mm:ss) |
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. |
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. |
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) |
returnResponseObjects | boolean | No | false | Set to true to obtain response objects corresponding to the response messages for this checkout. If no response messages are returned for the checkout, no response objects will be returned. |
barcode | string | No | - | Barcode for the checkout, used to lookup the transaction to retroactively apply it to a card (requires JSON v2) |
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. |
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. |
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) |
customRequestDate | string | No | - | Custom request date, used to set an alternative processing date on this checkout request. Must be turned on via brand setting. (format: yyyy-MM-dd HH:mm:ss) |
checkoutShippingTotal | number | No | - | Total amount spent for shipping in this transaction, used for campaign processing. Optional - if left out, shipping total will be set to 0. If this is specified, checkoutTotal should not include shipping Value should not be larger than 10000000. (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) |
receiptInformation | TransactionReceiptInformation | No | - | Optional, receipt specific information that will only be available for receipt related functionality |
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 |
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) |
customKeyValues | Array(CheckoutKeyValue) | No | - | Custom key-value pairs that can optionally be used for custom campaign triggering. This entire array is optional. |
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) |
orderMode | integer | No | - | Order mode, can optionally be specified on the checkout for reporting purposes. (requires JSON v2) |
checkoutTipTotal | number | No | - | Total tip amount with this transaction. Optional, if left out it will be considered 0. If this is specified, the checkoutTotal should not include the tip amount. The tip amount will typically not be used for campaign processing. In two-stage checkouts, the tip can be overwritten in the complete step. Value should not be larger than 10000000. (requires JSON v2) |
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) |
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. |
campaignChoices | Array(CampaignChoice) | No | - | Choices that a user selected for campaign execution. |
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) |
availableOptions | Array(CampaignOption) | No | - | Available campaign options that the user could select. NOTE: This will only be returned for checkout setup calls. (requires JSON v2) |
responseObjects | Array(ResponseObject) | No | - | Additional information relating to the responseMessages - only used if there are response messages present |
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. |
barcode | string | No | - | Barcode for the checkout. Will only be returned for anonymous checkouts where it was specified in the request |
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. |
CommunicationActivityRequest
Used to place CommunicationActivity requests, which can be used to get a list of historic communication activity for a specific card / customer.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
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 communication activity rows to skip before returning results. Value should not be smaller than 0. Value should not be larger than 1000. (requires JSON v2) |
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) |
cardNumber | string | Yes | - | Card number to request the communication activity history for. |
CommunicationActivityResponse
Response from CommunicationActivity requests.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
requestRef | string | Yes | - | Unique request reference, can be used for debugging or tracking individual requests / responses. |
communicationRows | Array(CommunicationRow) | No | - | A list of all matching communication activity rows. At most 100 rows will be returned. (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. |
rowCount | integer | No | - | Total amount of communication rows for the specified card. (requires JSON v2) |
CommunicationRow
Represents a communication activity row for a card. This is typically an incoming or outgoing message
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
experimentVariant | integer | No | - | If this communication resulted from a multi-variant experiment (A/B tests, etc), this will indicate the variant that was sent. Will be 0 for the first variant, 1 for the next, etc. |
clickedNamedLinks | Array(string) | No | - | Optional, named links that were clicked for this communication. This only applies to shortlinks. |
longcode | string | No | - | Longcode associated with this communication, if this applies. |
flags | Array(string) | Yes | - | List of flags that are associated with this communication activity row. |
name | string | No | - | Optional, the name that goes with this communication row. Will be null in cases such as inbound communication activity. |
clickedNumberedLinks | Array(integer) | No | - | Optional, numbered links that were clicked for this communication. The first link in a communication starts at 0. |
channelType | string | No | - | Channel type, e.g. email, phone, direct (snailmail), etc.. Allowed values are only: Email, Mail, PhoneSms, PhoneMms, Other |
communicationType | string | No | - | Communication activity type, e.g. triggered by API traffic, blast (periodical campaign or other blast), a reply (either to an incoming message or an automated reply based on API activity, such as an SMS optin API request) or an inbound communication (from customer to Clutch). Allowed values are only: Response, Triggered, Blast, Inbound |
templateId | string | No | - | Optional, templateId for outgoing messages |
inboundMessage | string | No | - | In case of inbound messages, this will contain the inbound message contents. Will be abbreviated if this was an inbound mobile message exceeding 255 characters. |
experimentType | string | No | - | Type of experiment, will only be specified if this communication activity is related to an experiment (A/B test, holdout test, etc).. Allowed values are only: Holdout, Multivariant |
timestamp | integer | Yes | - | Date and time when this communication activity happened. The value is the number of milliseconds since January 1, 1970, 00:00:00 GMT. |
CouponAttribute
Representation of a coupon attribute.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
intValue | integer | No | - | Integer value of this attribute. Specified if and only if the data type of this attribute is an integer. |
attributeName | string | Yes | - | API name of this attribute. |
strValue | string | No | - | String value of this attribute. Specified if and only if the data type of this attribute is a string. |
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) |
newAttributes | Array(CouponAttribute) | No | - | Optional, new attributes to set on the coupon |
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, delete |
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. |
newPin | string | No | - | Optional, new PIN to set on the coupon Value should not be longer than 20 characters if it’s specified. |
CouponDetailsResponse
Response from a couponDetails request.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
couponValueType | string | No | - | Optional, can contain the coupon value type. |
firstIssuanceAmount | number | No | - | Optional, if this is a coupon attached to a card and the card had any issuances for balance specifically for this coupon, this is the amount of balance that was issued during the first issuance to the coupon. |
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. |
description | string | No | - | Optional, can contain the coupon description. |
isAllocated | boolean | No | false | Whether the coupon has been allocated already. |
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. |
couponValue | number | No | - | Optional, can contain the coupon value. Note - this is not the coupon balance! |
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. |
pin | string | No | - | Optional, the coupon PIN |
success | boolean | Yes | false | Success flag, true means the request was successfully processed. |
attributes | Array(CouponAttribute) | No | - | Optional, attributes for this coupon. Will be null if there are no attributes stored on this coupon. |
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. |
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 |
mobileCarrier | string | No | - | Display name for the mobile carrier for this customer. This field will not always be populated. |
gender | string | No | - | Allowed values are only: F, M |
city | string | No | - | - |
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. |
profileType | string | No | - | Vertical for this customer |
phonePref | string | No | - | Opt (I)n, Opt (O)ut for text messages. Allowed values are only: I, O |
state | 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 |
string | No | - | - | |
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. |
address2 | string | No | - | Second address line |
address1 | string | No | - | First address line |
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. |
affiliatedLocationObjects | Array(LocationData) | No | - | Affiliated Location Objects, will be limited to the first 20 affiliated locations in case the card has more. |
affiliatedLocations | Array(string) | No | - | Deprecated. External IDs of affiliated locations. Do not use this property, but instead get it from affiliatedLocationObjects. |
middleName | string | No | - | - |
postal | 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 |
CustomerStats
Statistics object for a single customer.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
lifetimeSpend | number | No | - | Sum of all checkout totals that were sent in during completed checkouts. Will be 0 if there aren’t any purchases. |
last60DaySpend | number | No | - | Sum of all checkout totals that were sent in during completed checkouts in the last 60 days. Will be 0 if there aren’t any purchases in the last 60 days. |
averageOrderValue | number | No | - | Average order value, or 0 if there aren’t any purchases. Defined as the lifetimeSpend divided by the total amount of completed checkouts. |
customerLifetimeValue | integer | No | - | Customer Lifetime Value, calculated as AOV * Purchases Per Year * Avg Years of Relationship. |
mostRecentPurchaseLocationName | string | No | - | Location name of the most recent purchase, if there is at least 1 purchase. |
mostRecentPurchaseDate | string | No | - | Date and time of the most recent purchase, in the format yyyy-MM-dd HH:mm:ss. Will only be present if there is at least 1 purchase. (format: yyyy-MM-dd HH:mm:ss) |
mostShoppedLocationName | string | No | - | Location name of the location where most purchases happened, if there is at least 1 purchase. |
totalCheckouts | number | No | - | Total amount of checkouts. |
mostShoppedLocationId | string | No | - | External location ID of the location where most purchases happened, if there is at least 1 purchase. |
averageBasketSize | number | No | - | Average basket size, or 0 if there aren’t any purchases. Defined as the average amount of line items per completed checkout. |
mostRecentPurchaseLocationId | string | No | - | External location ID of the most recent purchase, if there is at least 1 purchase. |
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. Passing in 0000-00-00 erases a previously set birthday. |
lastName | string | No | - | Last name, max length is 90 Value should not be longer than 90 characters if it’s specified. |
country | string | No | - | Country code, max length is 2 Value should not be longer than 2 characters if it’s specified. |
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 if it’s specified. |
city | string | No | - | City, max length is 75 Value should not be longer than 75 characters if it’s specified. |
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 if it’s specified. |
address1 | string | No | - | Address line 1, max length is 100 Value should not be longer than 100 characters if it’s specified. |
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 if it’s specified. |
mobilePhone | string | No | - | Mobile phone number, max length is 18. Must be a valid phone number in E.164 format, or an empty string Value should not be longer than 18 characters if it’s specified. |
sequenceNr | integer | No | - | Sequence Number. |
profileType | string | No | - | Vertical for this customer. Passing in an empty string will unset this property. |
phone | string | No | - | Phone number, max length is 18. Must be a valid phone number in E.164 format, or an empty string Value should not be longer than 18 characters if it’s specified. |
affiliatedLocations | CustomerUpdatesStringList | No | - | List of external location IDs customer is affiliated with. |
middleName | string | No | - | Middle name, max length is 40 Value should not be longer than 40 characters if it’s specified. |
state | string | No | - | State name, full name is allowed, max length is 75 Value should not be longer than 75 characters if it’s specified. |
postal | string | No | - | Postal code, max length is 10 Value should not be longer than 10 characters if it’s specified. |
anniversary | string | No | - | Anniversary, in the format yyyy-MM-dd, e.g. 2000-01-01. |
string | No | - | Email address, max length is 320 Value should not be longer than 320 characters if it’s specified. | |
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. |
CustomerUpdatesStringList
This object represents an update request for a property on a card that supports multiple string values being set.
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. Defaults to 'overwrite’. (requires JSON v2). Allowed values are only: appendUnique, overwrite, append |
values | Array(string) | No | - | List of values to set the field value to, when mode is set to 'overwrite’, passing a null value will unset the property. Only compatible with fields that are of a list type. (requires JSON v2) |
DiscountProduct
Represents the discount of a certain amount of a specific SKU in a checkout. If supplied the matching checkout product (sku and unitPrice) must be supplied in the products array on checkout
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
unitPrice | number | No | 0.0 | Price per unit of this product that was paid. |
quantityDiscounted | number | No | 1.0 | Product quantity that was discounted. Should be a positive number, larger than or equal to 0. |
sku | string | Yes | - | SKU that identifies the product. Should be a non-empty value. |
sequenceId | integer | No | - | Sequence id of the SKU that identifies the specific product that the discount should apply to. May be left empty but it is recommended specifying the value. |
EnrolledProgram
The details of the program that a card is enrolled to.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
name | string | No | - | The descriptive name of the program. |
enrollmentDate | string | No | - | The date the card was enrolled to the program. (format: yyyy-MM-dd HH:mm:ss) |
programId | string | No | - | Unique identifier to program type. |
EventRegistration
Representation of a custom event that should be added to a card.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
specificId | string | No | - | Low level ID for this event’s event type in combination with the categoryID. |
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. |
merchantName | string | No | - | Optional, the merchant name that was associated with this transaction, in case there was no location data available. (requires JSON v2) |
HistoricTransaction
Represents a transaction / API call that happened in the past.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
locationName | string | No | - | Location name of the location where this transaction was initiated. Will only be included if location names were requested. (requires JSON v2) |
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) |
isVoided | boolean | No | false | Boolean that’s set to true if and only if the transaction has been voided (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. It will not be included for child card transactions. If it is not being returned and you would like to access this field, please contact Clutch. (requires JSON v2) |
merchantName | string | No | - | Optional, the merchant name that was associated with this transaction, in case there was no location data available. This will only be returned if the flag includeMainBalanceUpdate was true in the request. (requires JSON v2) |
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. |
checkoutTotalAfterDiscounts | number | No | - | In case the transaction is a checkout, this field will indicate the checkout total after discounts, both pre-discounts and discounts issued by Clutch. Set includeMainBalanceUpdate in the request to true to include this field in the response. (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) |
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. It will not be included for child card transactions. |
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. |
mutationType | string | No | - | Mutation type flag (requires JSON v2). Allowed values are only: Campaign, Adjustment, Cashout, Transfer, Expiration, ReturnMerchandise, Void, Uknown, Hold, UpdateBalance |
issuanceIndex | integer | No | - | Optional, set to null for redemptions, otherwise orders issuance transactions starting from 1. Specific balance buckets (coupons) and balance types get their own indexes. (requires JSON v2) |
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) |
balanceBucket | BalanceBucket | No | - | Optional, this will typically be null. If this is specified, the balance mutation belongs to a specific 'bucket’ on the card, e.g. it’s balance that belongs to a certain coupon on the card. |
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) |
LifeCycleStats
Life cycle statistics object for a single customer.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
daysUntilAtRisk | integer | No | 0.0 | Days until a customer is estimated to be at risk. |
daysSinceMostRecentPurchase | integer | No | 0.0 | Days since customer last made a checkout. Does not include voids or returns. |
daysUntilChurn | integer | No | 0.0 | Days until a customer is estimated to have churned. |
lifeCycleState | string | No | - | Whether a customer is active, at risk of churning, or churned.. Allowed values are only: ATRISK, ACTIVE, CHURNED, NONE |
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. |
LocationData
Represents a Location object coming back from the API.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
name | string | No | - | Display name of the location |
externalId | string | No | - | External ID of the location |
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. |
OfferActivityRequest
Used to place OfferActivity requests, which can be used to get a list of historic offer activity for a specific card / customer.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
cardNumber | string | Yes | - | Card number to request the offer activity history for. |
OfferActivityResponse
Response from OfferActivity requests.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
requestRef | string | Yes | - | Unique request reference, can be used for debugging or tracking individual requests / responses. |
offerRedeemedActivity | Array(OfferActivityRow) | No | - | A list of all offer activity for tracking redeemed offers. (requires JSON v2) |
offerSentActivity | Array(OfferActivityRow) | No | - | A list of all offer activity for tracking sent offers. (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. |
clickedDiscountNrs | Array(integer) | No | - | A set of all discount nrs that have been clicked. (requires JSON v2) |
OfferActivityRow
Represents an offer activity row for a card.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
discountNr | integer | No | 0.0 | Discount number associated with this offer activity. |
timestamp | string | Yes | - | Date and time when this offer activity happened. The value is in epoch seconds. (format: yyyy-MM-dd HH:mm:ss) |
PaymentAuthorizationMode
Payment authorization mode, may be provided for receipt functionality.
Parameter | Type | Required | Default | Description |
---|
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) |
receiptInformation | PaymentReceiptInformation | No | - | Optional - information specific for receipt printing or e-receipt generation that may be provided for payments using currency. When a two-stage checkout is used, this must be provided on the complete checkout call. (requires JSON v2) |
externalCampaignRuleId | string | No | - | Optional - if specified, all mutations coming from this payment method will be linked with this external campaign rule. (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, Bitcoin, Deferred, EBTCash, Check, Visa, DebitCard, Discover, Voyager, Cash, MasterCard, WrightExpress, GuaranteedCheck, PHH, DinersClub, EBT, 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) |
PaymentReceiptInformation
Optional information that may be provided specifically for receipt printing or e-receipt generation.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
paymentToken | string | No | - | Token that identifies the applied payment method. Value should not be longer than 36 characters if it’s specified. (requires JSON v2) |
paymentNetwork | string | No | - | Merchant identifier for the payment network that was used. For example, '02’ Value should not be longer than 3 characters if it’s specified. (requires JSON v2) |
cardHolderVerification | string | No | - | Method used to verify the card holder. (requires JSON v2). Allowed values are only: CVC, PIN, NONE, SIGNATURE |
cardHolderName | string | No | - | Name of the card holder. Value should not be longer than 60 characters if it’s specified. (requires JSON v2) |
authorizationCode | string | No | - | Alphanumeric authorization code Value should not be longer than 6 characters if it’s specified. (requires JSON v2) |
cardEntryMethod | string | No | - | Card number entry method. (requires JSON v2). Allowed values are only: SWIPE, CHIP, KEYED_IN, CONTACTLESS, ONLINE |
authorizationMode | string | No | - | Method that was used to authorize the provided payment method. (requires JSON v2). Allowed values are only: ISSUER, NONE, OFFLINE |
last4Digits | string | No | - | Last 4 digits of the used card. Value should not be longer than 4 characters if it’s specified. (requires JSON v2) |
PersonalOffer
Personal offer for a card
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
qualifyingSkus | Array(string) | No | - | Optional list of qualifying SKUs. Each SKU must be present with a quantity of at least 1 for a checkout to qualify to apply this offer. This list can contain up to 5 entries. |
percentageDiscount | integer | No | - | This is required if and only if the discountType is a percentage discount. This should be a number between 1 and 100, where 100 gives the product for free as a 100% discount. |
skus | Array(PersonalOfferProduct) | Yes | - | The list of products that can receive a discount as part of this offer. The offer will only apply if all of these products are present. Each entry will count as a quantity of 1. This list can contain up to 5 entries. |
discountType | string | Yes | - | The type of discount. For BOGO (buy one get one), you can only specify a single product.. Allowed values are only: percentageDiscount, newGroupPrice, bogo, absoluteDiscount |
newGroupPrice | number | No | - | This is required if and only if the discountType is a new group price. This will be the new group price, as a the total that will be charged for the group of target skus/products. |
activationDate | string | No | - | Optional, if not specified, the offer will be available for use immediately. Specify this property to set a date in the future when this offer becomes available. (format: yyyy-MM-dd HH:mm:ss) |
customId | integer | No | - | Optional ID that can be populated to track this offer. In exports and reports, you can find this ID when offers are redeemed. |
maxUsageCount | integer | No | - | Optional maximum usage count, defaults to 1. Offers can only be applied once per checkout, but if this property is specified, the offer can be used in more than one checkout. |
absoluteDiscount | number | No | - | This is required if and only if the discountType is an absolute discount. This is the discount to give in the target product’s native currency. |
expirationDate | string | Yes | - | Expiration date, must be at most 1 year into the future. (format: yyyy-MM-dd HH:mm:ss) |
PersonalOfferProduct
Representation of a product that can receive a discount as part of a personal offer.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
includeChildProducts | boolean | No | false | Flag, set this to true to also discount any child products attached to this SKU. This will be determined by the parent sequenceId |
sku | string | No | - | The SKU that identifies the product that will receive the discount |
PreDiscount
Represents a discount that was issued outside of the Clutch campaign logic.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
externalPromotionId | string | No | - | Optional - if specified, all mutations coming from this preDiscount will be linked with this external promotion ID. Compared to external campaigns, external promotions can be used in larger quantities: you can have many more external promotions. External promotions can only be tracked for reporting purposes and won’t be visible in the API. (requires JSON v2) |
amount | number | Yes | - | Amount of this discount. Amount should be positive. |
product | DiscountProduct | No | - | Optionally represents the product this discount applies to. Should be an exact match of a product object passed in the products array on checkout. |
externalCampaignRuleId | string | No | - | Optional - if specified, all mutations coming from this preDiscount will be linked with this external campaign rule. (requires JSON v2) |
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. |
ProgramEnrollment
Program details that the card should be enrolled in.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
program | string | Yes | - | The program name to enroll/un-enroll card in |
enroll | boolean | Yes | false | Flag to specify to enroll or un-enroll card in program |
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. |
childCardNumber | string | No | - | The child card to reactivate, if not null, will activate the child card instead of the parent card |
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. |
recommendationType | string | No | - | Recommendation type. This field is required, values = [Personalized, Backup]. Allowed values are only: Backup, Personalized |
RenderTemplateRequest
Request to obtain a rendered template for a user.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
templateId | string | Yes | - | The ID of the template to test out. |
cardNumber | string | Yes | - | Card number to request the offer activity history for. |
RenderTemplateResponse
Response from RenderTemplate requests.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
requestRef | string | Yes | - | Unique request reference, can be used for debugging or tracking individual requests / responses. |
subject | string | No | - | Rendered template subject (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. |
body | string | No | - | Rendered template body (requires JSON v2) |
RequestLookupRequest
Used to place RequestLookup requests, which can be used to find information about a specific previous request.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
showDetailedMutations | boolean | No | false | Optional, defaults to false. If true, the response will include detailed balance mutations similar to those returned by CardHistory. |
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. |
vtUserId | string | No | - | User ID 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) |
employeeId | string | No | - | Employee 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) |
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 |
detailedHoldMutations | Array(HistoricTransactionBalanceUpdate) | No | - | Optional, will only be returned if showDetailedMutations was set to true. This field contains detailed balance mutation information, such as the mutation type. The amount of mutations can vary from the regular balanceMutations structure, as that might have rolled up sub-mutations. This field only include hold mutations. (requires JSON v2) |
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) |
detailedNonHoldMutations | Array(HistoricTransactionBalanceUpdate) | No | - | Similar to detailedHoldMutations, except only containing non-hold mutations. (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) |
ResponseObject
Represents an object containing more details relating to a response message.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
message | string | No | - | The content of the response message this response object belongs to |
campaignRuleUUID | string | No | - | The UUID of the campaign rule triggering the response message |
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 |
---|---|---|---|---|
customRequestDate | string | No | - | Custom request date, used to set an alternative processing date on this returnMerchandise request. Must be turned on via brand setting. (format: yyyy-MM-dd HH:mm:ss) |
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. |
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. |
merchantName | string | No | - | Optional, the merchant name to associate with this transaction, in case there is no location data available. Value should not be longer than 64 characters if it’s specified. (requires JSON v2) |
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 true (or not specified), and this return tries to return too many products, the request will fail. This flag defaults to true. 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) |
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. |
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. |
SKUDiscount
Object used for maintain relevant information when breaking down an ordel level discount to SKU level
Parameter | Type | Required | Default | Description |
---|
SearchFilters
Represents the filters used to search cards / customers.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
birthday | string | No | - | Use this filter to find all cards where the birthday of the primary customer linked to the card matches with the specified value. The format is yyyy-MM-dd, e.g. 2015-01-01 |
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. |
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. |
convertToCurrency | string | No | - | The target conversion to which the default currency on the resulting cards should be converted. |
includeInactive | boolean | No | false | Whether inactive cards or child 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. |
pin | string | No | - | Pin for the card, only used if pin validation is needed. |
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. |
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. If specified, only parent cards that have a matching child card will match. Of those matching parent cards, all child cards will still be returned if requested - regardless of these filters. |
limit | integer | No | 10.0 | How many results to return. Value should not be smaller than 1. Value should not be larger than 25. |
primaryDemographicCaseSensitive | boolean | No | false | Whether the filters for primary demographic fields should use case sensitive matching logic or not. Defaults to false. (requires JSON v2) |
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. |
customDemographicCaseSensitive | boolean | No | true | Whether the filters for custom demographic fields should use case sensitive matching logic or not. Defaults to true. (requires JSON v2) |
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 |
---|---|---|---|---|
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) |
metaData | boolean | No | false | Indicate if card meta data should be returned. Meta data includes owning location name, program type/name. (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) |
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) |
personalOffers | boolean | No | false | Indicate if personal offers should be returned. This can only be returned if a single card is selected. (requires JSON v2) |
decorationLang | string | No | - | Indicate the language to be used when decorating custom choice values. This field is only considered if decorateCustomValues is set to true. Defaults to English (“en”). |
isEnrolled | boolean | No | false | Indicate if the enrollment status and date per card / primary customer should be returned. |
events | boolean | No | false | Indicate if all events stored on cards should be returned for the matching card(s). |
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 balanceExpirations 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) |
decorateCustomValues | boolean | No | false | Indicate if the choice descriptions should be returned instead of just the choice values for brand demographics when a fieldType is integer and the Segment Filter type is choice (v2 brands only). If using with the Clutch SFMC connector, requires enablement in brand settings to reflect the field name in reporting. |
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. |
enrolledPrograms | boolean | No | false | Indicate if the programs that the card is enrolled in should be returned. (requires JSON v2) |
surveyResponses | boolean | No | false | Indicate if card affiliated location data should be returned. This flag is only considered if customer is also set to true. 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. (requires JSON v2) |
thirdPartyLinks | boolean | No | false | Indicate if the third party links data from the third party should be returned. |
mmsBounced | boolean | No | false | Indicate if the mmsBounced property of cards should be returned. |
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) |
affiliatedLocations | boolean | No | false | Indicate if card affiliated location data should be returned. This flag is only considered if customer is also set to true. (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. |
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) |
expiredBalances | boolean | No | false | If balances is set to true and balanceExpirations is also set to true, this flag indicates if expired balances should be still be returned. This will include balances that were expired before they were redeemed. |
customer | boolean | No | false | Indicate if main customer information should be returned for all results |
statistics | boolean | No | false | Indicate if card purchase statistics should be returned. Returns mostShoppedLocationId, mostSpentLocationId, and lastShoppedLocation. 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. (requires JSON v2) |
SendEmailTemplateRequest
Send an email template
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
senderId | string | Yes | - | The sender ID used to retrieve sender email. |
subscriptionListId | string | Yes | - | The subscription list ID. |
templateId | string | Yes | - | The ID of the template to send out. |
cardNumber | string | Yes | - | Card number of the recipient |
SendEmailTemplateResponse
Response from SendEmailTemplate 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. |
SubscriptionDetailsRequest
Request object to interact with subscriptionDetails.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
assignmentStartDate | string | No | - | The date the subscription starts. (format: yyyy-MM-dd HH:mm:ss) |
action | string | Yes | - | Action to take with the specified card number and the subscriptions assigned to it.. Allowed values are only: update, details, delete, assign |
assignmentDate | string | No | - | The date the subscription was assigned to the card. For update, and delete action, assignment date is used as an identifier for subscriptions. (format: yyyy-MM-dd HH:mm:ss) |
assignmentEndDate | string | No | - | The date the subscription ends. (format: yyyy-MM-dd HH:mm:ss) |
subscriptionId | string | No | - | Id of the subscription on the card. For assign, update, and delete, subscription id is needed to identify specific subscription id. |
cardNumber | string | Yes | - | Card number the subscription(s) are assigned to. |
status | string | No | - | The status of the subscription on the card. For details, if specified, only subscriptions of that status are returned. For assign and update, if specified, the new status of the subscription on the card.. Allowed values are only: Active, Inactive |
SubscriptionDetailsResponse
Response object for subscription details.
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. |
cardSubscriptions | Array(CardSubscription) | No | - | The list of subscriptions assigned to the card. |
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. |
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. |
shortcode | string | No | - | For mobile subscription lists that use shortcodes, this field will contain that shortcode. |
uuid | string | Yes | - | UUID of the list. |
SurveyFieldRegistration
Response that should be registered for a certain survey field. This model is only used for registrations, not for display. If a field response is included in an update to an existing survey response, the previous field response will be completely replaced with this new field response.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
numericalValue | integer | No | - | If setValue is true and the field type is a number, a boolean or a date, this field is required. If the field type is a date, specify the timestamp in epoch milliseconds. If the field type is boolean, specify 1 for true and 0 for false. |
stringValue | string | No | - | If setValue is true and the field type is text or enum, this field is required. If the field is defined as an enum, this should be one of the allowed values only, case sensitive. |
stringValues | Array(string) | No | - | If setValue is true and the field type is multiple choice enum, this field is required. This should only contain allowed values from the enum definition, case sensitive. |
fieldName | string | Yes | - | Internal field name for the field to which this response applies. |
setValue | boolean | Yes | false | Flag, set this to true to specify the value or set this to false to remove the field response from an existing survey response. |
numericalValues | Array(integer) | No | - | If setValue is true and the field type is a list of numbers, this field is required. |
SurveyFieldResponse
Representation of a previous response to a single survey field / question.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
dateValue | integer | No | - | This field is populated if the field type is a date. If specified, this is a value in epoch milliseconds. |
numericalValue | integer | No | - | This field is populated if the field type is a single number. |
enumDisplayOptions | Array(string) | No | - | If enumOptions is specified, this can optionally be specified as an array of the same length. It will contain the display names of each of the enumOptions, appearing in the same order as enumOptions. |
stringValue | string | No | - | This field is populated if the field type is text. |
stringValues | Array(string) | No | - | This field is populated if the field type is a list of text values. |
enumOptions | Array(string) | No | - | Optional, can contain a list of all string values that are allowed to be specified as stringValue / stringValues. These are the internal names used in the API as references. |
fieldName | string | Yes | - | Internal field name, only unique within the survey |
displayName | string | Yes | - | Display name for this survey field |
stringValueDisplay | string | No | - | This field is populated if the stringValue field is defined as an enum option and enum display values were defined for this field, in which case this will contain the display value for that enum option. |
boolValue | boolean | No | - | This field is populated if the field type is a boolean. |
numericalValues | Array(integer) | No | - | This field is populated if the field type is a list of numbers. |
stringValuesDisplay | Array(string) | No | - | This field is populated if the stringValues field is defined as list of enum options and enum display values were defined for thie field, in which case this will contain the matching display values for those enum options. |
SurveyResponse
Representation of a response to a single survey.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
date | integer | No | 0.0 | Date in which survey response was submitted |
surveyId | string | Yes | - | Survey ID |
sentDate | string | No | - | The date when the user first received a link to complete this survey. (format: yyyy-MM-dd HH:mm:ss) |
instanceId | string | Yes | - | Survey registration instance ID |
fieldResponses | Array(SurveyFieldResponse) | No | - | Responses to all fields in the survey. If a field is not included in this list, it was not filled out in the response. |
locationExternalId | string | No | - | The external location ID |
displayName | string | Yes | - | Display name for the survey |
SurveyResponseRegistration
Registration of a survey response, or survey response update.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
surveyId | string | Yes | - | The survey ID for the survey for which a response should be recorded. |
sentDate | string | No | - | The date when the user first received a link to complete this survey. (format: yyyy-MM-dd HH:mm:ss) |
instanceId | string | Yes | - | The instance ID of this survey response registration. |
fieldResponses | Array(SurveyFieldRegistration) | Yes | - | The fields to set for this survey response. If this card already has an existing response to the same survey, you can specify field responses to update or remove in this list. |
removeRegistration | boolean | No | - | Optional, set this to true to remove the survey response registration for the specified survey + instance ID for this card. |
SuspicionStats
Life cycle statistics object for a single customer.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
distinctLocations | integer | No | 0.0 | Number of locations shopped at in time interval. |
totalSpend | number | No | - | Total spend (in dollars) on valid checkouts in time period. |
averageDaysBetweenPurchase | integer | No | 0.0 | Average days between valid purchases in specified time interval. |
suspicionScore | integer | No | 0.0 | Measure of how suspicious is this card’s recent activity, from 0 to 100. Score of 1 is least likely to be suspicious. 100 is most likely to be suspicious. Score of 0 or null means N/A because card has no purchases in time interval under consideration |
frequency | integer | No | 0.0 | Number of purchases in specified time interval. |
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 if it’s specified. |
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. Passing in a cause of 'userOptOut’ will trigger an opt-out notification SMS if used in an opt-out request. |
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 if it’s specified. |
categories | Array(ThirdPartyCategory) | No | - | List of categories this card will be (un)subscribed from, requires optIn to be set to true. |
preventReOptIn | boolean | No | - | Optional, indicates whether the subscription should be not be re-opted-in at the global level if currently opted out. Intended only to be used for batch import customer updates |
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. |
optInSourceName | string | No | - | Name of the API opt in source to use. If this is specified, do not specify optInSourceId as well. It is recommended to specify the name rather than the id. optInSourceName or optInSourceId must be passed in for phone-related opt in requests. |
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. |
TransactionReceiptInformation
Optional transaction specific receipt information.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
registerId | string | No | - | Optional, store specific identifier for the register or lane processing the transaction. Value should not be longer than 9 characters if it’s specified. (requires JSON v2) |
transactionId | string | No | - | Optional, local or POS-specific transaction identifier that may differ from the global transaction id. Value should not be longer than 16 characters if it’s specified. (requires JSON v2) |
TransferRequest
Used to transfer a card in or out.
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 |
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. |
transferCoupons | boolean | No | false | Transfers in all unique coupons and used coupons to the target card, also appends the target card number to the allowedWithCards coupon property in Cassandra |
oldChildCardNumber | string | No | - | The old child card to transfer, only required for a transfer in. oldChildCardNumber, oldCardNumber, childCardNumber, and cardNumber all have to be specified to transfer in a child card. |
childCardNumber | string | No | - | The child card to transfer in or out. Both childCardNumber and cardNumber have to be specified to transfer out a child card. |
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. |
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; Overwrite 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 |
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. |
returnBalanceMutations | boolean | No | false | Return the list of balance mutations that get transferred, ONLY works on a transfer in request |
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). |
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 |
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 |
---|---|---|---|---|
balanceMutations | Array(CampaignBalanceMutation) | No | - | Return a list of balance mutations that were transferred, for transfer in requests only |
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. |
TransferredCardLookupRequest
Used to look up the most recent or active card in use for a transferred card number.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
cardNumber | string | Yes | - | The card number of the card that was transferred. |
TransferredCardLookupResponse
Response object for TransferredCardLookup
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. |
mostRecentCardNumber | string | No | - | Either the most recent card number that the given card number was transferred to, or null if no card found. |
TriggerCampaignRuleRequest
Request to place a triggerCampaignRule request.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
deviceType | string | No | - | Optional, can be populated with a specific device type to be used for any communication events that could get created during this API call. |
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. |
customRequestDate | string | No | - | Custom request date, used to set an alternative processing date on this updateAccount request. Must be turned on via brand setting. (format: yyyy-MM-dd HH:mm:ss) |
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. |
surveyResponses | Array(SurveyResponseRegistration) | No | - | Survey responses. These can be new responses or updates to existing responses. |
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. |
returnBalanceMutations | boolean | No | false | When set to true, returns a list of detailed balance mutation information for all balance updates. |
countAsEnrollment | boolean | No | false | Whether this transaction should always count as an enrollment for the primary customer, provided this customer is not enrolled yet. |
returnBalances | boolean | No | false | When set to true, returns the balance information for the specified card |
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. |
updatedPin | string | No | - | Updated pin, used only to change the pin on v2 cards. Value should not be longer than 6 characters if it’s specified. (requires JSON v2) |
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) |
programEnrollments | Array(ProgramEnrollment) | No | - | Programs to enroll or un-enroll the card to. (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 |
---|---|---|---|---|
balances | Array(CardBalance) | No | - | Balance data for the cardNumber that was used after the updateAccount request is processed. |
balanceMutations | Array(CampaignBalanceMutation) | No | - | A list of detailed balance mutation information for balance updates. |
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 |
---|---|---|---|---|
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. |
subtrackIndex | integer | No | - | Subtrack index, can be specified (either this, couponId, or neither, but never both) to indicate which bucket of balance it targeted for this mutation. This relates to balance punch subtrack balances. (requires JSON v2) |
returnBalanceExpirations | boolean | No | false | If returnBalances 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. (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) |
couponId | string | No | - | Coupon ID, can be specified to update balance for a specific coupon. Coupon balances are separate from main card balances. NOTE: This functionality is not supported for child card balances. (requires JSON v2) |
merchantName | string | No | - | Optional, the merchant name to associate with this transaction, in case there is no location data available. Value should not be longer than 64 characters if it’s specified. (requires JSON v2) |
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 |
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. |
customRequestDate | string | No | - | Custom request date, used to set an alternative processing date on this updateBalance request. Must be turned on via brand setting. (format: yyyy-MM-dd HH:mm:ss) |
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 |
suspensionReason | string | No | - | Describes reason for suspended account. Allowed values are only: lostOrStolenAccount, other, dataPrivacyRequest, duplicateAccount, employee, hacked, customer, spamPhishing |
childCardNumber | string | No | - | Child card number, can be specified to modify balance on a child card inside the root card. (requires JSON v2) |
customKeyValues | Array(CheckoutKeyValue) | No | - | Custom key-value pairs that can optionally be used for custom campaign triggering. This entire array is optional. |
balanceReference | string | No | - | A reference to add to issued balance. This can be specified for balance issuances only. Contact Clutch support for access. Value should not be longer than 25 characters if it’s specified. |
isCashout | boolean | No | false | Used for redemption only. Set to true if the redemption is being used to issue the balance remainder in cash due to customer request. This field can be used to comply with cash-out laws by state. isCashout cannot be used if a card contains any held balance(s). Balance cannot go negative, requested amount should reflect the amount needed to reduce the card balance to 0.00. |
cardNumber | string | Yes | - | Card of which to modify a balance |
returnDelayedBalances | boolean | No | false | If returnBalances 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 returnBalanceExpirations flag. (requires JSON v2) |
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 |
---|---|---|---|---|
customRequestDate | string | No | - | Custom request date, used to set an alternative processing date on this checkout request. Must be turned on via brand setting. (format: yyyy-MM-dd HH:mm:ss) |
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. |
usedCouponResets | boolean | No | false | When the original transaction was a checkout call, this flag indicates if coupons used by the original checkout should be reset. When this is set to true, coupons will be reset and will become available to be used again.Set to false to leave the coupons as used. Defaults to false. (requires JSON v2) |
failIfCouponsUsed | boolean | No | false | If disabledIssuedCoupons is true 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 false. |
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 | No | - | The card number that was used in the original request, this must be specified if the original call was non-anonymous. Note: anonymous request voiding requires JSON v2 access |
disableIssuedCoupons | boolean | No | true | When the original transaction was a checkout call, indicates whether coupons that were issued as part of the original checkout should be disabled. Defaults to true (requires JSON v2) |
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.
- Stage base URL:
https://api-stage.clutch.com/merchant/
- Production base URL:
https://api.clutch.com/merchant/
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. For requests hitting JSON v2: if the original request data is available, the response will also contain "previousRequestRef" . If the original call was placed less than 24 hours ago, the original response data will also be included in string format in "previousResponse" . Note that this will typically be the original JSON response as a string value in this error response. |
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. |
33 | The coupon set is empty. |
34 | Resources unavailable. Similar to an internal server error, but of temporary nature. Please try again soon. |
35 | Invalid request date. |
36 | Return exceeds checkout limits. |
37 | Coupon has already been used. |
38 | Event category does not exist. |
39 | Conversion rates for the specified operation are unknown. |
40 | The attempted currency conversion is not valid. |
41 | Balance type is not supported for this operation. |
42 | Request timeout, the request could not be received by the server within the maximum allowed time. Please try sending the request again. |
43 | The requested feature is not available for this brand. Please contact Clutch support for more information. |
44 | Could not perform any of the desired subscription preference updates. |
45 | Invalid check digit. |
46 | The card number that was requested to be created already exists. |
47 | Cannot complete request, because the payment methods for the original checkout were already reversed (can only reverse them once to prevent over-returning). |
48 | The selected card is no longer available, possibly due to overusage or fraud. Contact Clutch support for more information. |
49 | The specified request is not available, as it is too old. |
50 | Too many child cards. |
51 | Coupon has already expired, so can’t use it anymore in this request. |
52 | Some coupons were not used. |
53 | The rate limit allowed for this brand was exceeded. |
54 | The mobile carrier is not supported by the brand. |
55 | The phone number is invalid, i.e. not a mobile phone number. |
56 | Already opted in. The phone number is already opted into the list. |
57 | The SMS list UUID was not found for the brand. |
58 | Invalid custom card number. The custom card number was not found. |
59 | Opt in source invalid. The specified opt in source could not be found. |
60 | The custom card number was not found on an active card for the brand. |
61 | The custom card number was found on multiple active cards. |
62 | The specified promotion was not found. |
63 | The checkout contained an unknown SKU, and the request does not allow this. |
64 | Card overuse detected. The card has been suspended due to overuse. |
65 | The requested type of reissuance is not allowed for this card. |
66 | The sku reference on a pre discount was not found. |
67 | The phone number is already NOT opted into the list. |
68 | Checkout requested already associated with a card. |
69 | The cardSetId provided is not available for virtual allocation, please use a virtual card set or provide a card number with your allocation call. |
70 | The card in question has exceeded the daily limit of anonymous checkout claims. |
71 | Child cards not found. |
72 | Transfer child card from one parent card to another failed |
73 | The checkout has a "customRequestDate" dated earlier than the card’s last chronological checkout. |