API overview

What is the IHC API?

The IHC API allows you to compute IHC attribution results of your customer journeys via a simple Web API. Thereby, IHC attribution can be used for adhoc analyses of your customer journeys as well as for integration into any existing ETL process.

The following sections will explain what the usage requirements are and how you can get started using IHC attribution on your data.

Getting started

Register

Please register here and make an account, we will contact you upon registration to discuss the usage plan that fits best for you.

Upload Training Data

After granting you access to the Webservice, you will have the option to upload a training set of customer journeys (csv or json file) that we will use to tailer the IHC model to your business case. You also need to specify a “Conv_Type_ID” for this training set, thereby you can tailor the IHC model to different types of conversions in your business context (e.g. new and returning customers).

Making your first API Call

Endpoint Type

POST Request

Endpoint URL

https://api.ihc-attribution.com/v1/compute_ihc

URL Parameters

conv_type_id (str: specifying which conversion type the customer journeys belong to, same as specified during training)

Request Header

API Key under x-api-key

Request Body

list of sessions making up customer journeys

Request Body

Required Fields

FieldTypeDescriptionExample Values
conversion_idstrunique identifier of the customer journey'conversion_id_1'
session_idstrunique identifier of the session within the customer journey‘session_id_567’
timestampstrtimestamp of the session, can include timezone information (see example values)'2021-03-20 18:49:31' (format: '%Y-%m-%d %H:%M:%S') (alternatively) with timezone information: '2021-03-20 18:49:31 +0400' (format: '%Y-%m-%d %H:%M:%S %z')
channel_labelstrinformation about the channel of the given session‘Social Paid’, ‘SEO’...
holder_engagementint1 if session counts for holder phase, 0 if not0 or 1
closer_engagementint1 if session counts for closer phase, 0 if not0 or 1
conversionint1 if conversion happens during this session, 0 if not0 or 1

Optional Fields

FieldTypeDescriptionExample ValuesDefault Value
impression_interactionint1 if session is an ad impression, 0 if not0 or 10

Holder & Closer Engagement Classification

The IHC model requires some session-level classification, if the session contained some Holder or Closer phase related customer engagement.

Recap:
  • Holder phase: is a period of continued customer attention, product orientation and interest being kept,
  • Closer phase is where the action is taken, the homestretch and the checkout process.

Of course, you best know your products, your platform steps in the conversion funnel. Hence, you need to quantify if the customer’s session engagement is eligible for the Holder or Closer phase.

Example classifications rules:
  • holder_engagement = 1 , so session is eligible for Holder phase, if at least one of the following conditions is fulfilled in the session:
    • 3 or more general views
    • 2 or more product detail views or product searches
  • closer_engagement = 1, so the session is eligible for Closer phase, if at least one of the conditions is fulfilled in the session:
    • 3 or more general views AND at least 1 or more checkout related steps
    • conversion happened in the session

We highly recommend not to try to over-engineer these engagement classifications. The idea is to simply give the IHC algorithm some indication that the user was e.g. actively pursuing the product orientation for Holder engagement, or e.g. actively starting the checkout process for Closer engagement.

In case of questions, please contact us. We are happy to support you in the IHC setup.
import json
import requests


customer_journeys = [{'conversion_id': 'EU02785522',
  'session_id': '2020-12-27_0001_DE_82a8917d-d9cb-a665-a1ce-34e9a279445c',
  'timestamp': '2020-12-27 18:04:24',
  'channel_label': 'Shopping - Brand',
  'holder_engagement': 0,
  'closer_engagement': 0,
  'conversion': 0,
  'impression_interaction': 0},
 {'conversion_id': 'EU02785522',
  'session_id': '2021-01-05_0001_DE_82a8917d-d9cb-a665-a1ce-34e9a279445c',
  'timestamp': '2021-01-05 13:10:14',
  'channel_label': 'Affiliate',
  'holder_engagement': 1,
  'closer_engagement': 0,
  'conversion': 0,
  'impression_interaction': 0},
 {'conversion_id': 'EU02785522',
  'session_id': '2021-01-10_0001_DE_82a8917d-d9cb-a665-a1ce-34e9a279445c',
  'timestamp': '2021-01-10 16:58:36',
  'channel_label': 'SEA - Brand',
  'holder_engagement': 1,
  'closer_engagement': 0,
  'conversion': 0,
  'impression_interaction': 0},
 {'conversion_id': 'EU02785522',
  'session_id': '2021-01-10_0002_DE_82a8917d-d9cb-a665-a1ce-34e9a279445c',
  'timestamp': '2021-01-10 17:09:33',
  'channel_label': 'Email',
  'holder_engagement': 1,
  'closer_engagement': 1,
  'conversion': 1,
  'impression_interaction': 0}]

## Insert API Key here
api_key = '{api_key}'

## Insert Conversion Type ID here
conv_type_id = '{conv_type_id}'

api_url = "https://api.ihc-attribution.com/v1/compute_ihc?conv_type_id={conv_type_id}".format(conv_type_id = conv_type_id)

body = {
    'customer_journeys': customer_journeys
}

response = requests.post(
        api_url, 
        data=json.dumps(body), 
        headers= {
            'Content-Type': 'application/json',    
            'x-api-key': api_key
        }
    )

results = response.json()

print(f"Status Code: {results['statusCode']}")

print("-"*30)

print(f"Partial Failure Errors: {results['partialFailureErrors']}")

print("-"*30)

display(results['value'])
curl --location --request POST 'https://api.ihc-attribution.com/v1/compute_ihc?conv_type_id={conv_type_id}' \
--header 'Accept: */*' \
--header 'Accept-Encoding: gzip, deflate' \
--header 'Connection: keep-alive' \
--header 'Content-Type: application/json' \
--header 'x-api-key: {api_key}' \
--data-raw '{
    "customer_journeys": [
        {
            "conversion_id": "EU02785522",
            "session_id": "2020-12-27_0001_DE_82a8917d-d9cb-a665-a1ce-34e9a279445c",
            "timestamp": "2020-12-27 18:04:24",
            "channel_label": "Shopping - Brand",
            "holder_engagement": 0,
            "closer_engagement": 0,
            "conversion": 0,
            "impression_interaction": 0
        },
        {
            "conversion_id": "EU02785522",
            "session_id": "2021-01-05_0001_DE_82a8917d-d9cb-a665-a1ce-34e9a279445c",
            "timestamp": "2021-01-05 13:10:14",
            "channel_label": "Affiliate",
            "holder_engagement": 1,
            "closer_engagement": 0,
            "conversion": 0,
            "impression_interaction": 0
        },
        {
            "conversion_id": "EU02785522",
            "session_id": "2021-01-10_0001_DE_82a8917d-d9cb-a665-a1ce-34e9a279445c",
            "timestamp": "2021-01-10 16:58:36",
            "channel_label": "SEA - Brand",
            "holder_engagement": 1,
            "closer_engagement": 0,
            "conversion": 0,
            "impression_interaction": 0
        },
        {
            "conversion_id": "EU02785522",
            "session_id": "2021-01-10_0002_DE_82a8917d-d9cb-a665-a1ce-34e9a279445c",
            "timestamp": "2021-01-10 17:09:33",
            "channel_label": "Email",
            "holder_engagement": 1,
            "closer_engagement": 1,
            "conversion": 1,
            "impression_interaction": 0
        }
    ]
}'
var myHeaders = new Headers();
myHeaders.append("Accept", "*/*");
myHeaders.append("Accept-Encoding", "gzip, deflate");
myHeaders.append("Connection", "keep-alive");
myHeaders.append("Content-Type", "application/json");
myHeaders.append("x-api-key", "{api_key}");

var raw = JSON.stringify({
  "customer_journeys": [
    {
      "conversion_id": "EU02785522",
      "session_id": "2020-12-27_0001_DE_82a8917d-d9cb-a665-a1ce-34e9a279445c",
      "timestamp": "2020-12-27 18:04:24",
      "channel_label": "Shopping - Brand",
      "holder_engagement": 0,
      "closer_engagement": 0,
      "conversion": 0,
      "impression_interaction": 0
    },
    {
      "conversion_id": "EU02785522",
      "session_id": "2021-01-05_0001_DE_82a8917d-d9cb-a665-a1ce-34e9a279445c",
      "timestamp": "2021-01-05 13:10:14",
      "channel_label": "Affiliate",
      "holder_engagement": 1,
      "closer_engagement": 0,
      "conversion": 0,
      "impression_interaction": 0
    },
    {
      "conversion_id": "EU02785522",
      "session_id": "2021-01-10_0001_DE_82a8917d-d9cb-a665-a1ce-34e9a279445c",
      "timestamp": "2021-01-10 16:58:36",
      "channel_label": "SEA - Brand",
      "holder_engagement": 1,
      "closer_engagement": 0,
      "conversion": 0,
      "impression_interaction": 0
    },
    {
      "conversion_id": "EU02785522",
      "session_id": "2021-01-10_0002_DE_82a8917d-d9cb-a665-a1ce-34e9a279445c",
      "timestamp": "2021-01-10 17:09:33",
      "channel_label": "Email",
      "holder_engagement": 1,
      "closer_engagement": 1,
      "conversion": 1,
      "impression_interaction": 0
    }
  ]
});

var requestOptions = {
  method: 'POST',
  headers: myHeaders,
  body: raw,
  redirect: 'follow'
};

fetch("https://api.ihc-attribution.com/v1/compute_ihc?conv_type_id={conv_type_id}", requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));

output

The response object is a dictionary with following keys:

  • value [list of dicts]
  • partialFailureErrors [list of dicts]
  • statusCode [int]

value

List of dictionaries with computed IHC results.

Similar to the input format, you receive a list of dictionaries whereas each dictionary makes up one session that includes the fields: 

FieldTypeDescriptionExample Values
conversion_idstrunique identifier of the customer journey (user input)‘conversion_id_1’
session_idstrunique identifier of the session within the customer journey (user input)‘session_id_567’
initializernumericintializer attribution of this session in range [0-1] (sum up to 1 within customer journey)0.2
holdernumericholder attribution of this session in range [0-1] (sum up to 1 within customer journey as long as there is at least one holder engagement session in the customer journey)0.15
closernumericcloser attribution of this session in range [0-1] (sum up to 1 within customer journey)0.25
ihcnumericoverall ihc attribution of this session in range [0-1] (sum up to 1 within customer journey)0.18
[{'conversion_id': 'EU02785522',
  'session_id': '2020-12-27_0001_DE_82a8917d-d9cb-a665-a1ce-34e9a279445c',
  'initializer': 0.4723,
  'holder': 0.0,
  'closer': 0.0,
  'ihc': 0.2537},
 {'conversion_id': 'EU02785522',
  'session_id': '2021-01-05_0001_DE_82a8917d-d9cb-a665-a1ce-34e9a279445c',
  'initializer': 0.3635,
  'holder': 0.4067,
  'closer': 0.0,
  'ihc': 0.2524},
 {'conversion_id': 'EU02785522',
  'session_id': '2021-01-10_0001_DE_82a8917d-d9cb-a665-a1ce-34e9a279445c',
  'initializer': 0.1642,
  'holder': 0.4659,
  'closer': 0.0,
  'ihc': 0.1537},
 {'conversion_id': 'EU02785522',
  'session_id': '2021-01-10_0002_DE_82a8917d-d9cb-a665-a1ce-34e9a279445c',
  'initializer': 0.0,
  'holder': 0.1274,
  'closer': 1.0,
  'ihc': 0.3402}]

partialFailureErrors

List of dictionaries with partial errors.

In case you sent multiple customer journeys in the request, this object can be either an empty list or a list of dictionaries with partial errors specifying for which conversion_id or session_id there was an error. These are the fields: 

fieldtypedescriptionexample values
triggerdictionaryindication which conversion_id and/or session_id caused the error{'conversion_id': 'EU02785523', 'session_id': '2021-01-10_0002_DE_82a8917d-d9cb-a665-a1ce-34e9a279445c'}
reasonstrtext description of what the error is"Wrongly Formatted 'timestamp' field: 2021-01-10 17:09:71"
statusCodeintstatus code of the error (in development)406
[
   {
      "trigger":{
         "conversion_id":"EU02785523",
         "session_id":"2021-01-10_0002_DE_82a8917d-d9cb-a665-a1ce-34e9a279445c"
      },
      "reason":"Wrongly Formatted 'timestamp' field: 2021-01-10 17:09:71",
      "statusCode":406
   }
]

statusCode

Integer value with status code of the overall request and also for partial failures.

The error handling is still in development, below you can find the current status codes:

status CodeDescription
200The request has succeeded without errors
206The request has succeeded but there are partial errors
400Request Failure due to invalid input
406(in partial failures object) error in parsing customer journey

Limits and Quotas

The following API limits are currently in place. Note that the maximum number of monthly requests depends on the agreement upon registration.

LimitDescriptionValue
Maximum Monthly Requestsmaximum number of monthly requests that can be made with the provided API Key (resets on first day of each month)depending on agreement
Maximum Number of Customer Journeys in Single Requestnumber of customer journeys for which IHC can be computed with a single request call100
Maximum Number of Sessions in Single Requestnumber of sessions that can be sent in a single request call3000