NAV Navbar
shell python

Introduction

The CACI Data Coding API provides a secure interface, with real-time access to CACI data products. It allows you to retrieve in real-time, relevant information about your customers or prospects and create fully personalised customer experiences. The API allows your applications to perform real-time matching and return back data for single or batch API requests.

The CACI Data Coding API follows the REST conventions, offering responses in JSON format. To view the available data products and sample request code use the left navigation bar. You can get started making requests, after you have successfully authenticated. To authenticate you will need first to register with us and request API keys.

Authentication

The CACI Data Coding API implements OAuth 2.0 to allow developers to authenticate without exposing any credentials.

The authentication process consists of the following two steps:

  1. Acquire an access token
  2. Use the access token to make authenticated requests

Acquire an access token

Acquiring an access token requires a call to the CACI authentication server.

import requests
import base64
from jose import jwk, jwt
from jose.utils import base64url_decode

app_client_id = '<YOUR_CLIENT_ID>'
app_client_secret = '<YOUR_CLIENT_SECRET>'

plain_token_bytes = '{}:{}'.format(app_client_id, app_client_secret).encode('utf-8')
basic_auth_token = base64.b64encode(plain_token_bytes).decode('utf-8')

headers = {'authorization': 'Basic {}'.format(basic_auth_token)}

data={
    'grant_type': 'client_credentials', 
    'scope': '<YOUR_SCOPE>'
}

r = requests.post("https://auth.api.caci.co.uk/oauth2/token", 
                  headers=headers, 
                  data=data)

access_token_type = r.json()['token_type']
access_token = r.json()['access_token']
claims = jwt.get_unverified_claims(access_token)
curl "https://auth.api.caci.co.uk/oauth2/token" \
    --header "accept: application/json" \
    --header "authorization: Basic MG9hY..." \
    --data "grant_type=client_credentials&scope=customScope"

Response Example

{
    "access_token": "token",
    "token_type": "Bearer",
    "expires_in": 3600,
    "scope": "customScope"
}

HTTPS Parameters

Parameter Description
app client id Your client id
app client secret Your client secret

Note the parameters that are being passed:

If the credentials are valid, the application will receive back an access token. The resulting access token is tied to both your client and an individual CACI user, and is valid for a few minutes.

Authenticating requests

All requests must be authenticated with an access token supplied in the Authorization header using the Bearer scheme. Your client may only have one active access token at a time, per user. Acquiring a new access token will invalidate any other token you own for that user.

Ocean & Fresco Data

Ocean, CACI’s database of the UK population with over 500 attributes covering demographics, lifestyle, finance and digital behaviour, provides insight to help you better understand your customers and the market. The Data Coding API allows you to code up new and existing customer records in real-time to deliver personalised content and messaging across a range of digital touchpoints.

Every request to the Data Coding API passes through a highly secure, encrypted layer, that requires OAuth 2.0 authentication with unique API keys provided by CACI. Requests do not store any personally identifiable information. Every time an API request is made, a unique identifier is required with the call. This unique identifier allows you to track down any records that fail to be matched and enriched with CACI data.

Single Request

The single request allows you to retrieve Ocean or Fresco data for a single individual utilising personal information in a secure manner. You will need to follow the initial authentication workflow as mentioned in an earlier section in order to retrieve your authentication token.

Request Example


import requests

access_token = "YOUR_ACCESS_TOKEN"
api_url = "https://data.api.caci.co.uk/v1/ocean/single"

headers = {
    "Content-Type": "application/json",
    "Authorization": "Bearer {}".format(access_token)
}

payload = {
  "uid": "<YOUR UNIQUE ID>",
  "title": "<OPTIONAL_TITLE>",
  "forename": "<FIRST_NAME>",
  "initials": "<OPTIONAL_INITIAL>",
  "surname": "<LAST_NAME>",
  "address_line_1": "FIRST_LINE_OF_ADDRESS",
  "address_line_2": "OPTIONAL_SECOND_LINE_OF_ADDRESS",
  "address_line_3": "OPTIONAL_THIRD_LINE_OF_ADDRESS",
  "address_line_4": "OPTIONAL_FOURTH_LINE_OF_ADDRESS",
  "address_line_5": "OPTIONAL_FIFTH_LINE_OF_ADDRESS",
  "address_line_6": "OPTIONAL_SIXTH_LINE_OF_ADDRESS",
  "address_line_7": "OPTIONAL_SEVENTH_LINE_OF_ADDRESS",
  "postcode": "<POSTCODE>",
  "ocean_age": "<AGE IF KNOWN>",
  "ocean_gender":   "<GENDER IF KNOWN (M)ALE, (F)EMALE, (U)NKNOWN>",
  "ocean_addage":   "<AGE OF HEAD OF HOUSEHOLD IF KNOWN>",
  "ocean_couple":   "<RELATIONSHIP STATUS (C)OUPLE, (S)INGLE, (P)COHABITING NOT MARRIED>",  
  "fresco_age": "<SELECT FROM BANDS (1)=18-24, (2)=25-34, (3)=35-49, (4)=50-64, (5)=65-74, (6)=75+>",
  "fresco_kid": "<PRESENCE OF CHILDREN (0=NO, 1=YES)>",
  "fresco_gender":  "<GENDER IF KNOWN (M)ALE, (F)EMALE, (U)NKNOWN>",
  "fresco_iscouple":    "<(S)INGLE OR (C)OUPLE)>",
  "fresco_cds": "<(C)OUPLE / (S)INGLE / (D)EPENDENT>",
  "fresco_htype":   "<(D)ETACHED, (S)EMI-DETACHED, (T)ERRACED, (B)UNGALOW>",
  "fresco_tenure":  "<(O)WNER OCCUPIED, (P)RIVATELY RENTED, (S)OCIALLY RENTED>"
}

r = requests.post(api_url, json=payload, headers=headers)

curl -X POST https://data.api.caci.co.uk/v1/ocean/single \
  -H "Authorization: Bearer $access_token" \
  -H 'Content-Type: application/json' \  
  -d '{
    "uid": "<YOUR UNIQUE ID>",
    "title": "<OPTIONAL_TITLE>",
    "forename": "<FIRST_NAME>",
    "initials": "<OPTIONAL_INITIAL>",
    "surname": "<LAST_NAME>",
    "address_line_1": "FIRST_LINE_OF_ADDRESS",
    "address_line_2": "OPTIONAL_SECOND_LINE_OF_ADDRESS",
    "address_line_3": "OPTIONAL_THIRD_LINE_OF_ADDRESS",
    "address_line_4": "OPTIONAL_FOURTH_LINE_OF_ADDRESS",
    "address_line_5": "OPTIONAL_FIFTH_LINE_OF_ADDRESS",
    "address_line_6": "OPTIONAL_SIXTH_LINE_OF_ADDRESS",
    "address_line_7": "OPTIONAL_SEVENTH_LINE_OF_ADDRESS",
    "postcode": "<POSTCODE>",
    "ocean_age": "<AGE IF KNOWN>",
    "ocean_gender": "<GENDER IF KNOWN (M)ALE, (F)EMALE, (U)NKNOWN>",
    "ocean_addage": "<AGE OF HEAD OF HOUSEHOLD IF KNOWN>",
    "ocean_couple": "<RELATIONSHIP STATUS (C)OUPLE, (S)INGLE, (P)COHABITING NOT MARRIED>",  
    "fresco_age":   "<SELECT FROM BANDS (1)=18-24, (2)=25-34, (3)=35-49, (4)=50-64, (5)=65-74, (6)=75+>",
    "fresco_kid":   "<PRESENCE OF CHILDREN (0=NO, 1=YES)>",
    "fresco_gender":    "<GENDER IF KNOWN (M)ALE, (F)EMALE, (U)NKNOWN>",
    "fresco_iscouple":  "<(S)INGLE OR (C)OUPLE)>",
    "fresco_cds":   "<(C)OUPLE / (S)INGLE / (D)EPENDENT>",
    "fresco_htype": "<(D)ETACHED, (S)EMI-DETACHED, (T)ERRACED, (B)UNGALOW>",
    "fresco_tenure":    "<(O)WNER OCCUPIED, (P)RIVATELY RENTED, (S)OCIALLY RENTED>"
}'

Response Example

{
    "responses": [
        {
            "uid": "<YOUR_UNIQUE_ID>",
            "postcode": "<MATCHED_POSTCODE>",
            "cr_addurn": "<MATCHED_ADDRESS_UNIQUE_IDENTIFIER>",
            "cr_indurn": "<MATCHED_INDIVIDUAL_UNIQUE_IDENTIFIER>",
            "match_attrs": { "<LICENSED NUMBER OF MATCHED OCEAN OR FRESCO ATTRIBUTES>" }
        }
    ]
}

HTTPS Request

POST https://data.api.caci.co.uk/v1/ocean/single

HTTPS Body

Parameter Description
uid Unique ID (*required)
title The individual's title e.g Mr, Mrs, Ms, etc.
forename The first name
initials The individual's initial
surname The last name
gender The gender
address_line_1 First line of address
address_line_2 Second line of address
address_line_3 Third line of address
address_line_4 Fourth line of address
address_line_5 Fifth line of address
address_line_6 Sixth line of address
address_line_7 Seventh line of address
postcode Individual's postcode (*required)
ocean_age Individual's age if known
ocean_gender Gender M)ale, (F)emale, (U)nknown
ocean_addage Age of head of household
ocean_couple Relationship status (C)ouple, (S)ingle, (P)Cohabiting
fresco_age Select from bands (1)=18-24, (2)=25-34, (3)=35-49, (4)=50-64, (5)=65-74, (6)=75+
fresco_kid Presence of children 0 = No, 1 = Yes
fresco_gender Gender M)ale, (F)emale, (U)nknown
fresco_iscouple (S)ingle or (C)ouple
fresco_cds (C)ouple, (S)ingle, (D)ependent
fresco_htype (D)etached, (S)emi-detached, (T)erraced, (B)ungalow
fresco_tenure (O)wned occupied, (P)rivately rented, (S)ocially rented

Response

Returns JSON-encoded array containing Ocean or Fresco data

Parameter Description
uid Unique identifier
postcode The matched postcode
cr_addurn The matched address unique identifier
cr_indurn The matched individual unique identifier
match_attrs The licensed Ocean or Fresco attributes

Batch Request

Each HTTPS connection results in a certain amount of overhead. The CACI Data Coding API supports batch requests that can retrieve multiple records in one call. You can specify the number of records that need to be retrieved with the HTTP Header X-Request-Count. If the number of records requested does not match the number of records within the JSON body then an HTTP Code 400 Bad Request will return.

Request Example


import requests

access_token = "YOUR_ACCESS_TOKEN"
api_url = "https://data.api.caci.co.uk/v1/ocean/batch"

headers = {
    "Content-Type": "application/json",
    "Authorization": "Bearer {}".format(access_token)
    'X-Request-Count': '2'
}

request_body = '''{
        "requests": [
          {
            "uid": "<YOUR UNIQUE ID_1>",
            "title": "<OPTIONAL_TITLE>",
            "forename": "<FIRST_NAME>",
            "initials": "<OPTIONAL_INITIAL>",
            "surname": "<LAST_NAME>",
            "address_line_1": "FIRST_LINE_OF_ADDRESS",
            "address_line_2": "OPTIONAL_SECOND_LINE_OF_ADDRESS",
            "address_line_3": "OPTIONAL_THIRD_LINE_OF_ADDRESS",
            "address_line_4": "OPTIONAL_FOURTH_LINE_OF_ADDRESS",
            "address_line_5": "OPTIONAL_FIFTH_LINE_OF_ADDRESS",
            "address_line_6": "OPTIONAL_SIXTH_LINE_OF_ADDRESS",
            "address_line_7": "OPTIONAL_SEVENTH_LINE_OF_ADDRESS",
            "postcode": "<POSTCODE>",
            "ocean_age": "<AGE IF KNOWN>",
            "ocean_gender": "<GENDER IF KNOWN (M)ALE, (F)EMALE, (U)NKNOWN>",
            "ocean_addage": "<AGE OF HEAD OF HOUSEHOLD IF KNOWN>",
            "ocean_couple": "<RELATIONSHIP STATUS (C)OUPLE, (S)INGLE, (P)COHABITING NOT MARRIED>",  
            "fresco_age":   "<SELECT FROM BANDS (1)=18-24, (2)=25-34, (3)=35-49, (4)=50-64, (5)=65-74, (6)=75+>",
            "fresco_kid":   "<PRESENCE OF CHILDREN (0=NO, 1=YES)>",
            "fresco_gender":    "<GENDER IF KNOWN (M)ALE, (F)EMALE, (U)NKNOWN>",
            "fresco_iscouple":  "<(S)INGLE OR (C)OUPLE)>",
            "fresco_cds":   "<(C)OUPLE / (S)INGLE / (D)EPENDENT>",
            "fresco_htype": "<(D)ETACHED, (S)EMI-DETACHED, (T)ERRACED, (B)UNGALOW>",
            "fresco_tenure":    "<(O)WNER OCCUPIED, (P)RIVATELY RENTED, (S)OCIALLY RENTED>"
          },
          {
            "uid": "<YOUR UNIQUE ID_2>",
            "title": "<OPTIONAL_TITLE>",
            "forename": "<FIRST_NAME>",
            "initials": "<OPTIONAL_INITIAL>",
            "surname": "<LAST_NAME>",
            "address_line_1": "FIRST_LINE_OF_ADDRESS",
            "address_line_2": "OPTIONAL_SECOND_LINE_OF_ADDRESS",
            "address_line_3": "OPTIONAL_THIRD_LINE_OF_ADDRESS",
            "address_line_4": "OPTIONAL_FOURTH_LINE_OF_ADDRESS",
            "address_line_5": "OPTIONAL_FIFTH_LINE_OF_ADDRESS",
            "address_line_6": "OPTIONAL_SIXTH_LINE_OF_ADDRESS",
            "address_line_7": "OPTIONAL_SEVENTH_LINE_OF_ADDRESS",
            "postcode": "<POSTCODE>",
            "ocean_age": "<AGE IF KNOWN>",
            "ocean_gender": "<GENDER IF KNOWN (M)ALE, (F)EMALE, (U)NKNOWN>",
            "ocean_addage": "<AGE OF HEAD OF HOUSEHOLD IF KNOWN>",
            "ocean_couple": "<RELATIONSHIP STATUS (C)OUPLE, (S)INGLE, (P)COHABITING NOT MARRIED>",  
            "fresco_age":   "<SELECT FROM BANDS (1)=18-24, (2)=25-34, (3)=35-49, (4)=50-64, (5)=65-74, (6)=75+>",
            "fresco_kid":   "<PRESENCE OF CHILDREN (0=NO, 1=YES)>",
            "fresco_gender":    "<GENDER IF KNOWN (M)ALE, (F)EMALE, (U)NKNOWN>",
            "fresco_iscouple":  "<(S)INGLE OR (C)OUPLE)>",
            "fresco_cds":   "<(C)OUPLE / (S)INGLE / (D)EPENDENT>",
            "fresco_htype": "<(D)ETACHED, (S)EMI-DETACHED, (T)ERRACED, (B)UNGALOW>",
            "fresco_tenure":    "<(O)WNER OCCUPIED, (P)RIVATELY RENTED, (S)OCIALLY RENTED>"
          }
        ]
  }
'''
r = requests.post(api_URL, headers=headers, json=request_body)

curl -X POST "https://data.api.caci.co.uk/v1/ocean/batch" \
  -H "Authorization: Bearer $access_token" \
     "X-Request-Count: $record_count" \
  -d '{
        "requests": [
          {
            "uid": "<YOUR UNIQUE ID_1>",
            "title": "<OPTIONAL_TITLE>",
            "forename": "<FIRST_NAME>",
            "initials": "<OPTIONAL_INITIAL>",
            "surname": "<LAST_NAME>",
            "address_line_1": "FIRST_LINE_OF_ADDRESS",
            "address_line_2": "OPTIONAL_SECOND_LINE_OF_ADDRESS",
            "address_line_3": "OPTIONAL_THIRD_LINE_OF_ADDRESS",
            "address_line_4": "OPTIONAL_FOURTH_LINE_OF_ADDRESS",
            "address_line_5": "OPTIONAL_FIFTH_LINE_OF_ADDRESS",
            "address_line_6": "OPTIONAL_SIXTH_LINE_OF_ADDRESS",
            "address_line_7": "OPTIONAL_SEVENTH_LINE_OF_ADDRESS",
            "postcode": "<POSTCODE>",
            "ocean_age": "<AGE IF KNOWN>",
            "ocean_gender": "<GENDER IF KNOWN (M)ALE, (F)EMALE, (U)NKNOWN>",
            "ocean_addage": "<AGE OF HEAD OF HOUSEHOLD IF KNOWN>",
            "ocean_couple": "<RELATIONSHIP STATUS (C)OUPLE, (S)INGLE, (P)COHABITING NOT MARRIED>",  
            "fresco_age":   "<SELECT FROM BANDS (1)=18-24, (2)=25-34, (3)=35-49, (4)=50-64, (5)=65-74, (6)=75+>",
            "fresco_kid":   "<PRESENCE OF CHILDREN (0=NO, 1=YES)>",
            "fresco_gender":    "<GENDER IF KNOWN (M)ALE, (F)EMALE, (U)NKNOWN>",
            "fresco_iscouple":  "<(S)INGLE OR (C)OUPLE)>",
            "fresco_cds":   "<(C)OUPLE / (S)INGLE / (D)EPENDENT>",
            "fresco_htype": "<(D)ETACHED, (S)EMI-DETACHED, (T)ERRACED, (B)UNGALOW>",
            "fresco_tenure":    "<(O)WNER OCCUPIED, (P)RIVATELY RENTED, (S)OCIALLY RENTED>"
          },
          {
            "uid": "<YOUR UNIQUE ID_2>",
            "title": "<OPTIONAL_TITLE>",
            "forename": "<FIRST_NAME>",
            "initials": "<OPTIONAL_INITIAL>",
            "surname": "<LAST_NAME>",
            "address_line_1": "FIRST_LINE_OF_ADDRESS",
            "address_line_2": "OPTIONAL_SECOND_LINE_OF_ADDRESS",
            "address_line_3": "OPTIONAL_THIRD_LINE_OF_ADDRESS",
            "address_line_4": "OPTIONAL_FOURTH_LINE_OF_ADDRESS",
            "address_line_5": "OPTIONAL_FIFTH_LINE_OF_ADDRESS",
            "address_line_6": "OPTIONAL_SIXTH_LINE_OF_ADDRESS",
            "address_line_7": "OPTIONAL_SEVENTH_LINE_OF_ADDRESS",
            "postcode": "<POSTCODE>",
            "ocean_age": "<AGE IF KNOWN>",
            "ocean_gender": "<GENDER IF KNOWN (M)ALE, (F)EMALE, (U)NKNOWN>",
            "ocean_addage": "<AGE OF HEAD OF HOUSEHOLD IF KNOWN>",
            "ocean_couple": "<RELATIONSHIP STATUS (C)OUPLE, (S)INGLE, (P)COHABITING NOT MARRIED>",  
            "fresco_age":   "<SELECT FROM BANDS (1)=18-24, (2)=25-34, (3)=35-49, (4)=50-64, (5)=65-74, (6)=75+>",
            "fresco_kid":   "<PRESENCE OF CHILDREN (0=NO, 1=YES)>",
            "fresco_gender":    "<GENDER IF KNOWN (M)ALE, (F)EMALE, (U)NKNOWN>",
            "fresco_iscouple":  "<(S)INGLE OR (C)OUPLE)>",
            "fresco_cds":   "<(C)OUPLE / (S)INGLE / (D)EPENDENT>",
            "fresco_htype": "<(D)ETACHED, (S)EMI-DETACHED, (T)ERRACED, (B)UNGALOW>",
            "fresco_tenure":    "<(O)WNER OCCUPIED, (P)RIVATELY RENTED, (S)OCIALLY RENTED>"
          }
        ]
  }' 

Response Example

{
    "responses": [
        {
            "status": 200,
            "uid": "<YOUR_UNIQUE_ID 1>",
            "postcode": "<MATCHED_POSTCODE>",
            "cr_addurn": "<MATCHED_ADDRESS_UNIQUE_IDENTIFIER>",
            "cr_indurn": "<MATCHED_INDIVIDUAL_UNIQUE_IDENTIFIER>",
            "match_attrs": { "<LICENSED NUMBER OF MATCHED OCEAN OR FRESCO ATTRIBUTES>" }
        },
        {
            "status": 200,
            "uid": "<YOUR_UNIQUE_ID 2>",
            "postcode": "<MATCHED_POSTCODE>",
            "cr_addurn": "<MATCHED_ADDRESS_UNIQUE_IDENTIFIER>",
            "cr_indurn": "<MATCHED_INDIVIDUAL_UNIQUE_IDENTIFIER>",
            "match_attrs": { "<LICENSED NUMBER OF MATCHED OCEAN OR FRESCO ATTRIBUTES>" }
        }
    ]
}

HTTPS Request

Returns JSON-encoded array with Ocean or Fresco data.

POST https://data.api.caci.co.uk/v1/ocean/batch

HTTPS Header

Parameter Required Description
X-Request-Count Yes The number of records requested

HTTPS Body

Parameter Description
uid Unique ID (*required)
title The individual's title e.g Mr, Mrs, Ms, etc.
forename The first name
initials The individual's initial
surname The last name
gender The gender
address_line_1 First line of address
address_line_2 Second line of address
address_line_3 Third line of address
address_line_4 Fourth line of address
address_line_5 Fifth line of address
address_line_6 Sixth line of address
address_line_7 Seventh line of address
postcode Individual's postcode (*required)
ocean_age Individual's age if known
ocean_gender Gender M)ale, (F)emale, (U)nknown
ocean_addage Age of head of household
ocean_couple Relationship status (C)ouple, (S)ingle, (P)Cohabiting
fresco_age Select from bands (1)=18-24, (2)=25-34, (3)=35-49, (4)=50-64, (5)=65-74, (6)=75+
fresco_kid Presence of children 0 = No, 1 = Yes
fresco_gender Gender M)ale, (F)emale, (U)nknown
fresco_iscouple (S)ingle or (C)ouple
fresco_cds (C)ouple, (S)ingle, (D)ependent
fresco_htype (D)etached, (S)emi-detached, (T)erraced, (B)ungalow
fresco_tenure (O)wned occupied, (P)rivately rented, (S)ocially rented

Response

Returns JSON-encoded array containing Ocean or Fresco data for each Identity

Parameter Description
status HTTP return code
uid Unique identifier
postcode The matched postcode
cr_addurn The matched address unique identifier
cr_indurn The matched individual unique identifier
match_attrs The licensed Ocean or Fresco attributes

Segment Models

The Segment Models endpoint produces customer segment data that can be used across the business to improve engagement with new and potential customers by determining:

Single Request

This allows you to request the segment for the specified individual. You will need to follow the initial authentication workflow as mentioned in an earlier section in order to retrieve your authentication token.

Request Example


import requests

access_token = "YOUR_ACCESS_TOKEN"
api_url = "https://data.api.caci.co.uk/v1/segments/single"

headers = {
    "Content-Type": "application/json",
    "Authorization": "Bearer {}".format(access_token)
}

payload = {
  "uid": "<YOUR UNIQUE ID>",
  "title": "<OPTIONAL_TITLE>",
  "forename": "<FIRST_NAME>",
  "initials": "<OPTIONAL_INITIAL>",
  "surname": "<LAST_NAME>",
  "address_line_1": "FIRST_LINE_OF_ADDRESS",
  "address_line_2": "OPTIONAL_SECOND_LINE_OF_ADDRESS",
  "address_line_3": "OPTIONAL_THIRD_LINE_OF_ADDRESS",
  "address_line_4": "OPTIONAL_FOURTH_LINE_OF_ADDRESS",
  "address_line_5": "OPTIONAL_FIFTH_LINE_OF_ADDRESS",
  "address_line_6": "OPTIONAL_SIXTH_LINE_OF_ADDRESS",
  "address_line_7": "OPTIONAL_SEVENTH_LINE_OF_ADDRESS",
  "postcode": "<POSTCODE>",
  "segment_params": "<KEY_VALUE_PAIRS_WITH_SEGMENTATION_MODEL_PARAMETERS>"
}

r = requests.post(api_url, json=payload, headers=headers)

curl -X POST https://data.api.caci.co.uk/v1/segments/single \
  -H "Authorization: Bearer $access_token" \
  -H 'Content-Type: application/json' \  
  -d '{
    "uid": "<YOUR UNIQUE ID>",
    "title": "<OPTIONAL_TITLE>",
    "forename": "<FIRST_NAME>",
    "initials": "<OPTIONAL_INITIAL>",
    "surname": "<LAST_NAME>",
    "address_line_1": "FIRST_LINE_OF_ADDRESS",
    "address_line_2": "OPTIONAL_SECOND_LINE_OF_ADDRESS",
    "address_line_3": "OPTIONAL_THIRD_LINE_OF_ADDRESS",
    "address_line_4": "OPTIONAL_FOURTH_LINE_OF_ADDRESS",
    "address_line_5": "OPTIONAL_FIFTH_LINE_OF_ADDRESS",
    "address_line_6": "OPTIONAL_SIXTH_LINE_OF_ADDRESS",
    "address_line_7": "OPTIONAL_SEVENTH_LINE_OF_ADDRESS",
    "postcode": "<POSTCODE>",
    "segment_params": "<KEY_VALUE_PAIRS_WITH_SEGMENTATION_MODEL_PARAMETERS>"
}'

Response Example

  {
    "uid": "<YOUR_UNIQUE_ID>",
    "postcode": "<MATCHED_POSTCODE>",
    "cr_addurn": "<MATCHED_ADDRESS_UNIQUE_IDENTIFIER>",
    "cr_indurn": "<MATCHED_INDIVIDUAL_UNIQUE_IDENTIFIER>",
    "segment_info": {"<LICENSED SEGMENTATION MODEL>"}
  }

HTTPS Body

POST https://data.api.caci.co.uk/v1/segments/single

HTTPS Body

Parameter Description
uid Unique ID (*required)
title The individual's title e.g Mr, Mrs, Ms, etc.
forename The first name
initials The individual's initial
surname The last name
gender The gender
address_line_1 First line of address
address_line_2 Second line of address
address_line_3 Third line of address
address_line_4 Fourth line of address
address_line_5 Fifth line of address
address_line_6 Sixth line of address
address_line_7 Seventh line of address
postcode Individual's postcode (*required)
segment_params Segmentation model parameters (*required)

Response

Returns JSON-encoded array containing the customer segments

Parameter Description
uid Unique identifier
postcode The matched postcode
cr_addurn The matched address unique identifier
cr_indurn The matched individual unique identifier
segment_info The licensed segmentation model

Batch Request

The batch Segments endpoint supports batch requests that can retrieve multiple records in one call. You can specify the number of records that need to be retrieved with the HTTP Header X-Request-Count. If the number of records requested does not match the number of records within the JSON body then an HTTP Code 400 Bad Request will return.

Request Example


import requests

access_token = "YOUR_ACCESS_TOKEN"
api_url = "https://data.api.caci.co.uk/v1/segments/batch"

headers = {
    "Content-Type": "application/json",
    "Authorization": "Bearer {}".format(access_token)
    'X-Request-Count': '2'
}

request_body = '''{
        "requests": [
          {
            "uid": "<YOUR UNIQUE ID_1>",
            "title": "<OPTIONAL_TITLE>",
            "forename": "<FIRST_NAME>",
            "initials": "<OPTIONAL_INITIAL>",
            "surname": "<LAST_NAME>",
            "address_line_1": "FIRST_LINE_OF_ADDRESS",
            "address_line_2": "OPTIONAL_SECOND_LINE_OF_ADDRESS",
            "address_line_3": "OPTIONAL_THIRD_LINE_OF_ADDRESS",
            "address_line_4": "OPTIONAL_FOURTH_LINE_OF_ADDRESS",
            "address_line_5": "OPTIONAL_FIFTH_LINE_OF_ADDRESS",
            "address_line_6": "OPTIONAL_SIXTH_LINE_OF_ADDRESS",
            "address_line_7": "OPTIONAL_SEVENTH_LINE_OF_ADDRESS",
            "postcode": "<POSTCODE>",
            "segment_params": "<KEY_VALUE_PAIRS_WITH_SEGMENTATION_MODEL_PARAMETERS>"
          },
          {
            "uid": "<YOUR UNIQUE ID_2>",
            "title": "<OPTIONAL_TITLE>",
            "forename": "<FIRST_NAME>",
            "initials": "<OPTIONAL_INITIAL>",
            "surname": "<LAST_NAME>",
            "address_line_1": "FIRST_LINE_OF_ADDRESS",
            "address_line_2": "OPTIONAL_SECOND_LINE_OF_ADDRESS",
            "address_line_3": "OPTIONAL_THIRD_LINE_OF_ADDRESS",
            "address_line_4": "OPTIONAL_FOURTH_LINE_OF_ADDRESS",
            "address_line_5": "OPTIONAL_FIFTH_LINE_OF_ADDRESS",
            "address_line_6": "OPTIONAL_SIXTH_LINE_OF_ADDRESS",
            "address_line_7": "OPTIONAL_SEVENTH_LINE_OF_ADDRESS",
            "postcode": "<POSTCODE>",
            "segment_params": "<KEY_VALUE_PAIRS_WITH_SEGMENTATION_MODEL_PARAMETERS>"
          }
        ]
  }
'''
r = requests.post(api_URL, headers=headers, json=request_body)

curl -X POST "https://data.api.caci.co.uk/v1/segments/batch" \
  -H "Authorization: Bearer $access_token" \
     "X-Request-Count: $record_count" \
  -d '{
        "requests": [
          {
            "uid": "<YOUR UNIQUE ID_1>",
            "title": "<OPTIONAL_TITLE>",
            "forename": "<FIRST_NAME>",
            "initials": "<OPTIONAL_INITIAL>",
            "surname": "<LAST_NAME>",
            "address_line_1": "FIRST_LINE_OF_ADDRESS",
            "address_line_2": "OPTIONAL_SECOND_LINE_OF_ADDRESS",
            "address_line_3": "OPTIONAL_THIRD_LINE_OF_ADDRESS",
            "address_line_4": "OPTIONAL_FOURTH_LINE_OF_ADDRESS",
            "address_line_5": "OPTIONAL_FIFTH_LINE_OF_ADDRESS",
            "address_line_6": "OPTIONAL_SIXTH_LINE_OF_ADDRESS",
            "address_line_7": "OPTIONAL_SEVENTH_LINE_OF_ADDRESS",
            "postcode": "<POSTCODE>",
            "segment_params": "<KEY_VALUE_PAIRS_WITH_SEGMENTATION_MODEL_PARAMETERS>"
          },
          {
            "uid": "<YOUR UNIQUE ID_2>",
            "title": "<OPTIONAL_TITLE>",
            "forename": "<FIRST_NAME>",
            "initials": "<OPTIONAL_INITIAL>",
            "surname": "<LAST_NAME>",
            "address_line_1": "FIRST_LINE_OF_ADDRESS",
            "address_line_2": "OPTIONAL_SECOND_LINE_OF_ADDRESS",
            "address_line_3": "OPTIONAL_THIRD_LINE_OF_ADDRESS",
            "address_line_4": "OPTIONAL_FOURTH_LINE_OF_ADDRESS",
            "address_line_5": "OPTIONAL_FIFTH_LINE_OF_ADDRESS",
            "address_line_6": "OPTIONAL_SIXTH_LINE_OF_ADDRESS",
            "address_line_7": "OPTIONAL_SEVENTH_LINE_OF_ADDRESS",
            "postcode": "<POSTCODE>",
            "segment_params": "<KEY_VALUE_PAIRS_WITH_SEGMENTATION_MODEL_PARAMETERS>"
          }
        ]
  }' 

Response Example

{
    "responses": [
        {
            "status": 200,
            "uid": "<YOUR_UNIQUE_ID 1>",
            "postcode": "<MATCHED_POSTCODE>",
            "cr_addurn": "<MATCHED_ADDRESS_UNIQUE_IDENTIFIER>",
            "cr_indurn": "<MATCHED_INDIVIDUAL_UNIQUE_IDENTIFIER>",
            "segment_info": {"<LICENSED SEGMENTATION MODEL>"}
        },
        {
            "status": 200,
            "uid": "<YOUR_UNIQUE_ID 2>",
            "postcode": "<MATCHED_POSTCODE>",
            "cr_addurn": "<MATCHED_ADDRESS_UNIQUE_IDENTIFIER>",
            "cr_indurn": "<MATCHED_INDIVIDUAL_UNIQUE_IDENTIFIER>",
            "segment_info": {"<LICENSED SEGMENTATION MODEL>"}
        }
    ]
}

HTTPS Request

Returns JSON-encoded array with Ocean or Fresco data.

POST https://data.api.caci.co.uk/v1/segments/batch

HTTPS Header

Parameter Required Description
X-Request-Count Yes The number of records requested

HTTPS Body

Parameter Description
uid Unique ID (*required)
title The individual's title e.g Mr, Mrs, Ms, etc.
forename The first name
initials The individual's initial
surname The last name
gender The gender
address_line_1 First line of address
address_line_2 Second line of address
address_line_3 Third line of address
address_line_4 Fourth line of address
address_line_5 Fifth line of address
address_line_6 Sixth line of address
address_line_7 Seventh line of address
postcode Individual's postcode (*required)
segment_params Segmentation model parameters (*required)

Response

Returns JSON-encoded array containing segments for each Identity

Parameter Description
status HTTP return code
uid Unique identifier
postcode The matched postcode
cr_addurn The matched address unique identifier
cr_indurn The matched individual unique identifier
match_attrs The licensed Ocean or Fresco attributes
segment_info The licensed segmentation model

Acorn API

Acorn is a powerful consumer classification that segments the UK population. By analysing demographic data, social factors, population and consumer behaviour, it provides precise information and an understanding of different types of people. Acorn provides valuable consumer insight helping you target, acquire and develop profitable customer relationships and improve service delivery.

Single Request

This is used to retrieve Acorn data using a postcode and a user defined unique identifier. The identifier can be anything from a number or an alphanumeric GUID that is used within a database system or application. Postcodes can be supplied in any format as long as they do not contain invalid characters.

Request Example


import requests

access_id = "YOUR_APP_ACCESS_ID"
access_secret = "YOUR_APP_ACCESS_SECRET"
api_URL = "https://acorn.api.caci.co.uk/v1/entities"

headers = {
    'authorization': '{} {}'.format(access_id, access_secret)    
}

params = {
  'uid': '<YOUR ID>',
  'postcode': '<YOUR_POSTCODE>'
}

r = requests.get(api_URL, headers=headers, params=params)

curl "https://acorn.api.caci.co.uk/v1/entities?postcode=<YOUR POSTCODE>&uid=<YOUR ID>"
  -H "Authorization: Bearer $access_token"

Response Example

{
    "responses": [
        {
            "uid": "<YOUR ID>",
            "acorn_type_desc": "Better-off villagers",
            "acorn_category": "1",
            "acorn_type": "10",
            "acorn_group": "C",
            "status": 200,
            "postcode": "<YOUR_POSTCODE>",
            "acorn_group_desc": "Mature Money",
            "acorn_category_desc": "Affluent Achievers"
        }
    ]
}

HTTPS Request

GET https://acorn.api.caci.co.uk/v1/entities

HTTPS Parameters

Parameter Description
uid Unique ID
Postcode The location

Response

Returns JSON-encoded array containing Acorn data

Parameter Description
Acorn Group Unique group, 18 groups in total
Acorn Group Desc Living style
Acorn Type Unique type, 62 types in total
Acorn Type Desc Category of the living style
Postcode Full postcode
Acorn Category Desc Life style
Acorn Category Unique category, 6 categories in total
uid Unique ID

Batch Request

Each HTTPS connection results in a certain amount of overhead. The CACI Data Coding API supports batch requests that can retrieve multiple records in one call. You can specify the number of records that need to be retrieved with the HTTPS Header X-Request-Count. If the number of records requested does not match the number of records within the JSON body then an HTTP Code 400 Bad Request will return.

Request Example

access_id = "YOUR_APP_ACCESS_ID"
access_secret = "YOUR_APP_ACCESS_SECRET"
api_URL = "https://acorn.api.caci.co.uk/v1/batch"

headers = {
    'authorization': '{} {}'.format(access_id, access_secret),
    'X-Request-Count': '3'
}

request_body = '''{
        "requests": [
          {
            "uid": "<YOUR ID 1>",
            "postcode": "<YOUR_POSTCODE 1>"
          },
          {
            "uid": "<YOUR ID 2>",
            "postcode": "<YOUR_POSTCODE 2>"
          },
          {
            "uid": "<YOUR ID 3>",
            "postcode": "<YOUR_POSTCODE 3>"
          }
        ]
  }
'''
r = requests.post(api_URL, headers=headers, json=request_body)

curl "https://acorn.api.caci.co.uk/v1/batch" \
  -H "Authorization: Bearer $access_token" \
     "X-Request-Count: $record_count" \
  -d '{
        "requests": [
          {
            "uid": "<YOUR ID 1>",
            "postcode": "<YOUR_POSTCODE 1>"
          },
          {
            "uid": "<YOUR ID 2>",
            "postcode": "<YOUR_POSTCODE 2>"
          },
          {
            "uid": "<YOUR ID 3>",
            "postcode": "<YOUR_POSTCODE 3>"
          }
        ]
  }' 

Response Example

{
    "responses": [
        {
            "acorn_type_desc": "Comfortably-off families in modern housing",
            "acorn_category": "3",
            "acorn_type": "24",
            "uid": "<YOUR ID 1>",
            "acorn_group": "G",
            "status": 200,
            "postcode": "<YOUR_POSTCODE 1>",
            "acorn_group_desc": "Successful Suburbs",
            "acorn_category_desc": "Comfortable Communities"
        },
        {
            "acorn_type_desc": "Metropolitan professionals",
            "acorn_category": "2",
            "acorn_type": "16",
            "uid": "<YOUR ID 2>",
            "acorn_group": "D",
            "status": 200,
            "postcode": "<YOUR_POSTCODE 2>",
            "acorn_group_desc": "City Sophisticates",
            "acorn_category_desc": "Rising Prosperity"
        },
        {
            "acorn_type_desc": "Better-off villagers",
            "acorn_category": "1",
            "acorn_type": "10",
            "uid": "<YOUR ID 3>",
            "acorn_group": "C",
            "status": 200,
            "postcode": "<YOUR_POSTCODE 3>",
            "acorn_group_desc": "Mature Money",
            "acorn_category_desc": "Affluent Achievers"
        }
    ]
}

HTTPS Request

Returns JSON-encoded array with Acorn data.

POST https://acorn.api.caci.co.uk/v1/batch

HTTPS Header

Parameter Required Description
X-Request-Count Yes The number of records requested

Response

Parameter Description
uid Unique ID
Acorn Group Unique group, 18 groups in total
Acorn Group Desc Living style
Acorn Type Unique type, 62 types in total
Acorn Type Desc Category of the living style
Postcode Full postcode
Acorn Category Desc Life style
Acorn Category Unique category, 6 categories in total

Changelog

Recent changes and additions to CACI Data Coding API v1. Changes marked with [Versioned] include a versioned change and are only available for applications that specify that version or later. Other changes are available for all versions.

2020-10-20

Errors

The CACI Data Coding API uses standard HTTP response codes to indicate success or failure. On each response detailed messages are returned to provide information on the error that occured.

HTTP response codes

Code Error Id Description
200 OK All is going well.
207 Multi-status Successful return on batch requests.
400 Bad Request The request parameters are invalid or the number of requested records does not match the record count provided or missing required request parameters.
401 Unauthorized Your API key is wrong or your token has expired.
405 Method Not Allowed You are using an incorrect HTTP verb. Double check whether it should be POST/GET/DELETE/etc.
404 Not found Match not found for specified query.
429 Too Many Requests Your application is exceeding its rate limit.
500 Internal Server Error We had a problem with our server. Try again later.
504 Gateway Timeout Something has timed out.

Authentication errors

On authentication, errors contain additional information to follow the OAuth specification. Specifically, they contain the error key with the following values:

Value Meaning
invalid_token The access token passed is invalid or has expired.

Security

CACI hosts the Data Coding API in a secure AWS environment physically located in the EU with high physical security and ISO/IEC 27001 certification. No data associated with the service is stored in any other territory.

The AWS secure virtual private cloud has high levels of physical security and is ISO/IEC 27001 certified. Digital security is such that access to the data is only via a CACI controlled secure authentication layer, that utilises an OAuth 2.0 workflow that provides authentication tokens to the client and that are being refreshed automatically. Additionally, data-in-transit is protected by transport layer security (TLS 1.2) while data-at-rest is encrypted.

What is TLS?

Transport Layer Security (TLS) is a cryptographic protocol used to provide encryption over a network. The predecessor to TLS is with Secure Sockets Layer (SSL). Our REST APIs use TLS 1.2 which is the latest version of TLS and has been around for a number of years. It's well supported in web browsers and modern operating systems. TLS 1.2 represents the industry benchmark for encryption and will ensure the highest level of security for your applications and data.

AWS Data Centres

AWS data centres are housed in nondescript facilities. Physical access is strictly controlled both at the perimeter and at building ingress points by professional security staff utilising video surveillance, intrusion detection systems, and other electronic and physical means. Authorised staff must pass two-factor authentication a minimum of two times to access data centre floors. All visitors and contractors are required to present identification and are signed in and continually escorted by authorised staff.

AWS has established formal policies and procedures to delineate the minimum standards for logical access to AWS platform and infrastructure hosts. AWS conducts criminal background checks, as permitted by law, as part of pre-employment screening practices for employees and commensurate with the employee’s position and level of access.