Self-Classification Rules API
If you are a DMP client, you can implement the Oracle Data Cloud self-classification category and rule web services to independently classify the page and user attributes ingested from your site or classify your onboarded offline data. Classification is the process in which your data that has been transferred into the Oracle Data Cloud platform is collected and mapped to categories in your private taxonomy. Implementing the category and rule APIs enables you to create hierarchical categories within your taxonomy and write rules that define when an attribute (and user) get added to each category.
With the Rules API, you can create classification rules based on URLs and key-value pairs (phints) that map the user data extracted from your site with the categories you created with the Categories API.
Important: The Self-Classification Rules API will be deprecated in the near future and replaced with the Rules API. You should begin migrating to the Rules API to take advantage of its advanced features for creating and maintaining your classification rules.
Note: Users no longer create campaigns in the Oracle Data Cloud platform UI. The campaign workflow is now part of the audience workflow. The platform still uses campaigns to manage audience data delivery however. They are created automatically when a UI user delivers an audience. In the APIs, you create and use campaigns as before.
In this topic
Explore the API
The embedded I/O doc below enables you to explore the API. The I/O doc explains the parameters for each method and provides templates for your calls. You cannot make live API calls from the tool, however.
Open the link below in a new tab to see the I/O doc in a three-pane format.
selfclassificationrules.docs.apiary.io/
For help with this API, contact My Oracle Support (MOS).
Service URI
The URI for the Rules API is:
services.bluekai.com/Services/WS/classificationRules
Use cases
Bulk classification rule update
To configure multiple classification rules at the same time using the new bulk update feature:
- In the headers field, set the Content-Type to multipart/form-data and specify an encapsulation boundary parameter.
headers = {"Content-Type": "multipart/form-data; boundary=a8d84ae2e7db4676843c7df172b68bfc","Accept": "application/json","User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:22.0) Gecko/20100101 Firefox/22.0"}
- In the PUT body, enter the opening encapsulation boundary.
- Set the Content-Disposition to form-data, and include a name parameter that is set to categoryRule, and an optional filename parameter.
- Set the Content-Type to text/tab-separated-values.
- Enter tab-separated values for the category to be created or updated. You must insert fields for any values that you do not specify.
- Enter the closing encapsulation boundary.
Example: Body of a bulk import PUT request that updates a phint-based rule and a URL-based rule
'''--a8d84ae2e7db4676843c7df172b68bfcContent-Disposition: form-data; name="ruleFile"; filename="Classification-Rules.tsv"Content-Type: text/tab-separated-values51315433344168myPhintRulephintcolor-is=blue:item-is=shirt51415415:15433280107:280106myURLRuleurl-exacthttps://www.bluekai.com,https://www.eloqua.com,https://www.responsys.com--a8d84ae2e7db4676843c7df172b68bfc--'''
The following table lists the tab-separated values that can be included in the request:
Column | Field | Data type | Description |
---|---|---|---|
1 | id
|
string | Either the permanent ID of an existing rule or a temporary ID that you provide for a new rule you are creating (include one or more alphanumeric characters in the ID to avoid collisions with the IDs of existing rules) |
2 | site_ids
|
list | A colon-separated list of site IDs for which this rule is applicable If you leave this field blank, the rule is applicable to all the site IDs in your seat. |
3 | category_ids
|
list | A colon-separated list category IDs for which this rule is applicable |
4 | name
|
string | A unique, descriptive name for the rule The rule will be listed by this name in the Oracle Data Cloud platform UI. The name may be a maximum of 255 characters. |
5 | rule_type
|
enum | Enter one of the following values:
|
6 | rules
|
list |
|
URL rules that include multibyte encodings
To create rules for URLs that include multibyte encodings, you must encode the percentage symbols (%) in the UTF-8 encoded characters. For example, to create a URL rule for https://www.マネジメント/site.html
, convert マネジメント to UTF-8, which results in the following encoding:
%e3%83%9e%e3%83%8d%e3%82%b8%e3%83%a1%e3%83%b3%e3%83%88
Encode the percentage symbols in the UTF-8 encoding (convert each % symbol to %25), which results in the following encoding:
%25e3%2583%259e%25e3%2583%258d%25e3%2582%25b8%25e3%2583%25a1%25e3%2583%25b3%25e3%2583%2588
This results in the following encoded string:
https://www.com%2F%25e3%2583%259e%25e3%2583%258d%25e3%2582%25b8%25e3%2583%25a1%25e3%2583%25b3%25e3%2583%2588%2Fsite.html
See also: Percent-encoding
Bulk import demo
The sample_bulk_category_import.py Python code demonstrates how to do a bulk category import using the Rules API. To run this script, you must have the following:
- Python 2.7+
- Requests library 1.2.3 (or later)
You can use the pip package manager to help install the requests library. To download and install pip, install the requests library, and then delete the pip installation file, enter the following commands in your console:
curl -O https://bootstrap.pypa.io/get-pip.py
sudo python get-pip.py
sudo pip install requests
rm get-pip.py
To run this script, you need to create a TSV file named self-classification-rules.tsv that contains the rules you want and provides the following parameters:
url
: The URL of the production environment (services.bluekai.com)verbosity
: Enter a series of four verbose options for printing information.bkuid
: Your web service user keybksecretkey
: Your web service private key
For details, see the sample_self-classification-rules.tsv template, which includes instructions for editing. Before using the sample TSV file, you must remove all text other than the lines that include your values and you must rename the file to self-classification-rules.tsv.
The following example demonstrates the required syntax for calling this script:
classificationRule.py --url https://services.bluekai.com -v -v -v -v --bkuid WebServiceUserKey --bksecretkey WebServicePrivateKey
![Closed](../../Skins/Default/Stylesheets/Images/transparent.gif)
#! /usr/bin/env python -B
# -*- coding: utf-8 -*-
import sys, requests, json, argparse, unittest, hmac, base64, urllib, urlparse, hashlib
def cli_options():
parser = argparse.ArgumentParser(description='Demo for REST API')
parser.add_argument('-u','--url', default='https://localhost:8080/', help='Web service base URL')
parser.add_argument('-i','--bkuid', default='', help='BlueKai UID')
parser.add_argument('-k','--bksecretkey', default='', help='BlueKai Secret key')
parser.add_argument('-v','--verbose', default=0, action='count', help='Prints additional information')
return parser.parse_args()
args = cli_options()
URL = args.url.strip()
BKUID = args.bkuid
BKSECRETKEY = args.bksecretkey
VERBOSITY = args.verbose
USER_AGENT = {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:22.0) Gecko/20100101 Firefox/22.0'}
JSON_HEADERS = {'Content-Type': 'application/json', 'Accept':'application/json'}
COMMON_HEADERS = dict(USER_AGENT.items() + JSON_HEADERS.items())
class ClassificationRule():
res = False
def info(self, message, verbosityLevel = 1):
if VERBOSITY >= verbosityLevel:
if not isinstance(message, basestring):
print json.dumps(message, indent=4)
else:
print message
def prepare_headers(self, headers = None):
if headers is None:
return COMMON_HEADERS.copy()
else:
return dict(COMMON_HEADERS.items() + headers.items())
def parse_query_params(self, query):
parameterList = query.split('&')
params = {}
if len(parameterList) > 0:
for entry in parameterList:
kvPair = entry.split('=')
params[kvPair[0]] = kvPair[1] if len(kvPair) > 1 else '';
return params
def prepare_request(self, endpoint, method = 'GET', params = None, data = None, headers = None, files = None, sign=True):
if files is not None:
headers.pop('Content-Type', None)
req = requests.Request(method, URL + endpoint, data = data, headers = headers, files = files)
prepared = req.prepare()
if sign:
if params is None:
params = {}
parsedUrl = urlparse.urlparse(URL)
parsedEndpoint = urlparse.urlparse(endpoint)
servletPath = "" if parsedEndpoint.path.strip().startswith("/") else "Services/WS/"
urlPath = parsedUrl.path.strip('/')
if urlPath:
urlPath = urlPath + '/'
fullPath = '/'+ urlPath + servletPath + parsedEndpoint.path.strip('/')
stringToSign = method + fullPath
params = dict(params.items() + self.parse_query_params(parsedUrl.query).items() + self.parse_query_params(parsedEndpoint.query).items())
queryParameterStr = '';
for key in params.keys():
if len(key) > 0:
if isinstance(params[key], list):
for listItem in params[key]:
value = urllib.quote(str(listItem))
stringToSign += value
queryParameterStr += urllib.quote(key) + '=' + value + '&'
else:
value = urllib.quote(str(params[key]))
stringToSign += value
queryParameterStr += urllib.quote(key) + '=' + value + '&'
if prepared.body is not None:
stringToSign += prepared.body
h = hmac.new(BKSECRETKEY, stringToSign.strip(), hashlib.sha256)
s = base64.standard_b64encode(h.digest())
signature = urllib.quote_plus(s)
finalURL = parsedUrl.scheme + '://' + parsedUrl.netloc + fullPath + '?' + queryParameterStr + 'bkuid=' + BKUID + '&bksig=' + signature
else:
finalURL = URL + endpoint
self.info('Sending %s request to: %s' %(method, finalURL))
prepared.url = finalURL
if VERBOSITY >=4:
print "Request object:"
for key, value in prepared.headers.iteritems():
print "%s: %s" % (key, value)
if prepared.body is not None and len(prepared.body)>0:
print ""
print prepared.body
return prepared
def post(self, endpoint, payload = None, params = None, headers = None, files = None):
if payload is not None:
data = payload if isinstance(payload, basestring) else json.dumps(payload)
else:
data = None
self.res = requests.Session().send(self.prepare_request(endpoint, method = 'POST', params = params, data = data, files = files, headers = self.prepare_headers(headers)), verify = False)
return self
def test_bulk_self_class_create(self):
files = {'ruleFile': open('self-classification-rules.tsv', 'rb')}
created_rules = self.post('classificationRules', files = files, params={}).res.json()
self.info(created_rules, 2)
instance=ClassificationRule()
instance.test_bulk_self_class_create()
Related API calls
These are the API calls you will typically make before you use the Rules API:
Before Rules API | Use case |
---|---|
Containers API | The use case for the containers API depends on which data ingest method you are using to transfer your data into the Oracle Data Cloud platform (online ingest, offline onboard, user data API, or mobile ingest):
|
Self-Classification Category API | Add first-party categories to the self-classification tree in your private taxonomy. |
These are the API calls you will typically make after you use the Rules API:
After Rules API | Use case |
---|---|
Audiences API | Create a target audience that includes your self-classified first-party categories. |
Categories API | View your categories and their inventory. |
GET response summary
The Rules API GET request returns the classification rules used to map your categories with your site data. Here are the properties included for each rule:
Field | Type | Description |
---|---|---|
category_ids
|
list (category IDs) | A list of category IDs to which the classification rule applies |
created_at
|
date | A timestamp indicating when the rule was initially created |
id
|
integer | The unique ID assigned to the classification rule |
name
|
string | The user-specified name for classification rule |
partner_id
|
integer | The unique ID of the your partner seat to which the classification rule applies |
phints
|
list (phint definitions) | A list of your phint definitions, which contain the following properties:
|
referrer
|
boolean | Indicates whether the URL to be classified is the site URL (false) or the referrer URL (true) This field is only returned for URL-based rules. |
site_ids
|
list (site IDs) | A list of containers to which the classification rule applies |
status
|
enum | The status of the classification rule (Active , Creating , or Updating ) |
type
|
enum | The type of classification rule (phint or url ) |
updated_at
|
date | A timestamp indicating when the rule was last modified |
url
|
list (URLs) | A list of your URL definitions This field is only returned for URL-based rules. |
POST response errors
If the POST request for creating categories fails, the POST response will use one of the following HTTP status codes:
Code | Error message | Description |
---|---|---|
400 | Bad Request | The body of the POST response will contain short description of the problems with the POST request. |
401 | Unauthorized | You need to authenticate the request. See authentication and authorization for more information. |
403 | Forbidden | You have reached the maximum number of categories (by default, the limit is 100). |
404 | Not Found | The specified parent category is either not in your self-classification tree or is not in your Partner seat |
The body of the POST response will contain a list of error codes for each of the input attributes causing the error. The following example demonstrates a POST response listing the errors for a failed request:
{ "errors": {
"rule_id": [
"RULE_ID_INVALID"
],
"rule_name": [
"RULE_NAME_DULICATE"
],
},
"detail": "Bad request"
}
Self-Classification Category API