Enrichment API

Last updated on

The Contentsquare Enrichment API is organized around REST. Our API has predictable resource-oriented URLs, accepts form-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs.

Not a developer? Contact your CSM. They will direct you to the best solution to meet your data needs.

  • Base URL of the API:
    https://enrichment-api.{cloud}.contentsquare.com/v1/enrichments
    (this is a dynamic URL that you will retrieve in the API calls flow)
  • Current Version of the API: 1.0

What is Contentsquare?

Contentsquare is a next-gen Analytics tool that helps you understand how and why your users are interacting with your app, mobile and website.

What this API is about

Contentsquare relies on a web tracking tag or mobile SDK to track session-based data. By session we mean a user's visit on a website or app.

This API allows for enriching the behavioural data tracked by Contentsquare client-side, with other session-based data that can be sent server-side.

For example, you can start reconciling offline and online journeys by enriching web sessions data with phoning data for calls that were triggered from those sessions. As Contentsquare cannot access phone call data during a web session via its tag or SDK, the related data must be sent to Contentsquare server-side, once the calls are ended and processed. In Contentsquare, you can then create user segments based on this phoning data and start answering questions like: "how does a specific journey on my website impact my conversion on the phone?", or "How do users who end up making a qualitative call behave on my website?"

How it works: an overview

Making an integration based on the Enrichment API up and running goes through the following steps:

  1. As a starting point, the technology partner provides an integration schema to Contentsquare and gets listed in the Contentsquare integrations catalog
  2. Customers install the integration and provides a Contentsquare API key to the technology partner
  3. During web sessions, the technology partner pulls Contentsquare session information (project ID, session ID) that will be used by Contentsquare to match the data received server-side
  4. The technology partner can then send enrichment data batches:
    1. The technology partner authenticates with the API key provided by the customer, and receives both a JWT valid for 1 hour and a dynamic enrichment endpoint where the data should be sent
    2. The technology partner sends the data to the provided endpoint with a valid JWT

And here is a diagram summarizing the detailed interactions involved in the authentication flow for an integration based on the integration API:

Enrichment API Authentication Flow Diagram

We will detail each step in the following sections.

Definitions

Provider

A provider is the entity (usually a technology partner) that will enrich the data.

A provider is identified by a unique providerId by Contentsquare.

A provider will create integrations in order to be able to send data to Contentsquare.

Integration

An integration is created by a provider to declare what data will be sent to Contentsquare. It is represented by a data schema provided by the provider, in the form of a JSON object.

When data will be sent to Contentsquare, a specific integration will be authenticated and Contentsquare will check that enrichments abide by the schema of the integration.

An integration is identified by a unique integrationId by Contentsquare.

An integration can have multiple integration versions.

Integration version

An integration can have multiple schema versions, to allow for updating and versioning an integration while avoiding to break enrichments flows relying on a previous schema.

See the dedicated section to see how to manage an integration schema update.

Enrichment

An enrichment is a data instance that matches an integration schema. It is the data sent by the provider to enrich Contentsquare sessions.

If an enrichment does not meet the specified integration version schema, it will be rejected.

As several enrichments can be sent to enrich the same Contentsquare session, each enrichment for a specific session is indexed with an enrichment number.

Enrichment number

Each new enrichment for a specific session is indexed to be differentiated from the previous enrichments received for the same session.

Currently, no more than 3 enrichments can be sent per session, so enrichments will be indexed with a number from 1 to 3 included. The enrichment number should be specified by the provided but if not, it will be considered as being 1 by default.

The enrichment number can be used to update an existing enrichment: if for a session, an enrichment is pushed with the same index as a existing enrichment, it will get updated with the last enrichment received.

See the dedicated section to see how to manage an enrichment update.

Enrichment field

An enrichment field is a specific key in an enrichments data object.

Enrichment batch

An enrichment batch is a collection of enrichments, in the form of an array of JSON objects. Enrichments are sent in batch to the Enrichment API endpoint. Of course, nothing prevents the provider from sending a batch of one enrichment only.

For security purposes, if an enrichment gets rejected, the full batch will be rejected.

Session

A session is a visit of a user on a website or mobile app. The purpose of the Enrichment API is to enrich Contentsquare sessions data.

Creating an integration

Get in touch with your Contentsquare contact to provide the required information.

You will need to provide:

  • A data schema (in the form of a JSON object): see below
  • A name, logo and description of what the integration does and related use cases to be listed in the Contentsquare integrations catalog.

Schema format

{
  "fields": [
    // the list of fields
    {
      "name": "FIELD_NAME_1", // max 50 bytes
      "type": "STRING", // either "DATETIME", "INT", "FLOAT", "STRING" or "BOOL"
      "optional": true, // either true or false to make this field optional or not
      "label": "Field 1", // a business name that can be used in user interfaces
      "description": "A first field" // a business description that can be displayed in documentation pages and user interfaces
    },
    {
      "name": "FIELD_NAME_2",
      "type": "INT",
      "optional": false,
      "label": "Field 2",
      "description": "Another field"
    }
  ]
}

Data types

An enrichment field can be of one of the following types:

  • "STRING":
    • Min length: 0
    • Max length: 50 bytes
  • "INT":
    • Min integer: -2147483648
    • Max integer: 2147483647
  • "FLOAT":
    • Min float: -1.79769e+308
    • Min float: 1.79769eE+308
  • "BOOL":
    • Boolean values: true / false
  • "DATETIME":
    • Format: YYYY-MM-DDThh:mm:ssZ, e.g. "2022-07-26T14:47:35Z"

Limitations

  • A schema cannot include more than 10 fields of each type (so there can be up to 10 strings, 10 integers, 10 booleans etc.)
  • Key names length is limited to 30 bytes
  • Strings are limited to 50 bytes

Example

An example schema for a provider sending phone call data could look like this:

{
  "fields": [
    {
      "name": "answered",
      "type": "BOOL",
      "optional": true,
      "label": "Call answered",
      "description": "Whether the call was answered (true) or not (false)"
    },
    {
      "name": "call_duration",
      "type": "INT",
      "optional": false,
      "label": "Call duration",
      "description": "The call duration in milliseconds"
    },
    {
      "name": "call_client_rating",
      "type": "FLOAT",
      "optional": true,
      "label": "Client rating",
      "description": "The call rating left by the client after the call if any"
    },
    {
      "name": "call_center_name",
      "type": "STRING",
      "optional": false,
      "label": "Call center name",
      "description": "The name of the call center that made the call"
    },
    {
      "name": "call_datetime",
      "type": "DATETIME",
      "optional": false,
      "label": "Call date and time",
      "description": "The date and time at which the call started"
    }
  ]
}

Installing an integration

Once an integration has been created by a technology partner and is available in the Contentsquare integrations catalog, from there customers can install the integration.

When they go through the installation flow, customers are provided with a project ID and API key in the Contentsquare UI. Those 2 elements have to be provided to the technology partner so that the latter can know which project to send data for, and how to authenticate.

Retrieving Contentsquare session identifiers from the customer's website

Once an integration has been installed, the technology partner should start collecting Contentsquare session identifiers during web visits on the common customer's website. These identifiers will be used to attach the enrichment data to the right Contentsquare sessions when data will be received from the technology partner.

Those identifiers are:

  • The project ID: identifies the Contentsquare project ID where the data is stored
  • The user ID: identifies the Contentsquare anonymous user ID for the user visiting the website
  • The session number: identifies a specific session (as an ordered index) of the user ID (e.g. if Contentsquare has tracked 4 different sessions of the same anonymous user, the last session number will be 4)

How to get those Contentsquare session identifiers?

During a visit on a website, you can interact with Contentsquare’s tag to pull those identifiers via the afterPageView command (see the detailed documentation here). A JavaScript code using that command should look like this:

const yourCallback = (context) => {
  const projectId = context.projectId;
  const [userId, sessionNumber] = context.sessionKey.split(".");
  // store these Contentsquare session identifiers in your backend
};
 
window._uxa = window._uxa || [];
_uxa.push(["afterPageView", yourCallback]);

By calling this function you will get the project ID, user ID and session number of each session that are required to identify the Contentsquare sessions to be enriched.

Sending enrichment data batches to Contentsquare

Once you, the technology partner, have collected the required Contentsquare session identifiers, you can start enriching the Contentsquare data with its own information.

Sending a batch of enrichment data falls into 2 steps:

  • Authenticating and retrieving the right enrichment endpoint dynamically
  • Sending the enrichment data to this endpoint with a valid JWT

Authenticating and retrieving the dynamic enrichment endpoint

The authentication step has 2 objectives:

  • Retrieving a valid JWT that can be used to push enrichments for 1 hour
  • Retrieving the right enrichment endpoint dynamically (that depends on the customer's cloud)

Prerequisite

A valid API key.

HTTP Request

[tab] Request
  • Endpoint: https://api.contentsquare.com/v1/enrichment/jwt
  • Method: POST
  • Header: Authorization: Bearer {API_KEY}
  • Body: none
[tab] Response
{
  "payload": {
    "jwt": "{JWT}",
    "url": "{ENRICHMENT_ENDPOINT}"
  },
  "success": true
}
  • ENRICHMENT_ENDPOINT is the URL to be called to send the enrichment data
  • JWT is the token to be used to authenticate on the ENRICHMENT_ENDPOINT, in the format BASE_64_JWT_HEADER.BASE_64_JWT_BODY (you can decode each part with a base64 string decoder).
[tab] Errors
Unauthorized: 401
{
  "success": false,
  "errorMessage": "API Key is missing",
  "errorCode": "API_KEY_REQUIRED"
}
Forbidden: 403: revoked API key
{
  "success": false,
  "errorMessage": "Revoked API Key",
  "errorCode": "API_KEY_REVOKED"
}
Forbidden: 403: project not allowed
{
  "success": false,
  "errorMessage": "Project is not allowed to use API",
  "errorCode": "PROJECT_NOT_ALLOWED"
}

Example

[tab] Request
curl --request POST \
  --url https://api.contentsquare.com/v1/enrichment/jwt \
  --header 'Authorization: Bearer ZwXwUZ9z945UFzfpwNO9WJKOS3TmuVt8'
[tab] Response
{
  "payload": {
    "jwt": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IktJRCJ9.eyJpc3MiOiJlbnJpY2htZW50SW50ZWdyYXRpb24iLCJpYXQiOiJJQVQiLCJleHAiOiJFWFAiLCJ2ZXJzaW9uIjoiMSIsInByb2plY3RJZCI6MTYyLCJpbnRlZ3JhdGlvbklkIjoxMDB9",
    "url": "https://enrichment-api.ba.contentsquare.com/v1/enrichments"
  },
  "success": true
}

Sending data to the enrichment endpoint

Prerequisites

  • Step 3: the technology partner must have the knowledge of which Contentsquare project ID and sessions the data will enrich
  • Step 4.1: the technology partner must have a valid JWT and enrichment endpoint
  • All the enrichments of a batch sent to the enrichment endpoint have to match the schema version of the integration provided in the request (if an enrichment gets rejected, then the full batch will be rejected)

HTTP Request

[tab] Request
  • Endpoint (returned by the authentication call in step 4.1):
    https://enrichment-api.{cloud}.contentsquare.com/v1/enrichments
  • Method: POST
  • Header: Authorization: Bearer {JWT}
  • Body:
{
  "integrationVersion": 1, // required, provided by Contentsquare when creating a new schema
  "projectId": 1, // retrieved in step 3
  "enrichments": [
    {
      "userId": "{USER_ID}", // string, retrieved in step 3
      "sessionNumber": {SESSION_NUMBER}, // integer, retrieved in step 3
      "enrichmentNumber": 1, // integer, max 3, optional (will be 1 if not specified)
      "enrichment": {
        "field1": "Some string",
        "field2": 42,
        "field3": 3.14,
        "field4": "2022-03-23T00:10:30Z",
        "field5": true
      }
    }
  ]
}
  • integrationVersion: a schema version for the integration must be specified so that Contentsquare can know which schema the data must match. Every time a new schema is created, Contentsquare provides the provider with a new integration version. The provider must take care of sending data that match the right schema version. If the provider has only one schema registered, then the integrationVersion should remain 1 by default.
  • enrichmentNumber: as a Contentsquare session can be enriched with up to 3 enrichments, each enrichment must be indexed so that it can potentially be updated later (see the dedicated section on how to update an enrichment). Index should start at 1 and can be max 3. If no enrichment number is specified by the provider, it will be considered as 1 by default (meaning that if the provider never specifies any enrichment number, any new enrichment for a session will overwrite the previous one and there will be only 1 enrichment per session - with index 1)
[tab] Response

Success 200

(Empty body)

[tab] Errors
Unauthorized: 401: invalid JWT token
{
  "message": "Unauthorized"
}
Bad request 400: data validation failed
{
  "message": "enrichments don't match expected payload"
}
Bad request 400: bad integration version
{
  "message": "bad integration version"
}

Example

[tab] Request
curl --location --request POST 'https://enrichment-api.ba.contentsquare.com/v1/enrichments' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IktJRCJ9.eyJpc3MiOiJlbnJpY2htZW50SW50ZWdyYXRpb24iLCJpYXQiOiJJQVQiLCJleHAiOiJFWFAiLCJ2ZXJzaW9uIjoiMSIsInByb2plY3RJZCI6MTYyLCJpbnRlZ3JhdGlvbklkIjoxMDB9' \
--data-raw '{
    "integrationVersion": 1,
    "projectId": 162,
    "enrichments": [
        {
            "userId": "aaa-aaa-aaa",
            "sessionNumber": 5,
            "enrichmentNumber": 1,
            "enrichment": {
                "has_called": true,
                "call_duration": 3532,
                "call_client_rating": 4.5,
                "call_center_name": "RENNES",
                "call_date": "2022-01-01T20:02:22Z"
            }
        },
        {
            "userId": "aaa-aaa-aaa",
            "sessionNumber": 5,
            "enrichmentNumber": 2,
            "enrichment": {
                "has_called": true,
                "call_duration": 2293,
                "call_client_rating": 2,
                "call_center_name": "RENNES",
                "call_date": "2022-01-01T18:09:54"
            }
        }
    ]
}'
[tab] Response

Success 200

Limitations

  • EnrichmentNumber:
    • Min: 1
    • Max: 3
  • Number of enrichments per batch: max 200
  • Sessions that started more than 7 days ago cannot be enriched (enrichment for those sessions will not be rejected but no data will be available in the Contentsquare platform in the end)

Update an integration schema

If the provider wants to update the schema of an integration, it can be done thanks to the integrationVersion key. By incrementing the version, the provider can decide to add, delete or edit keys of the data schema while protecting enrichment flows that may prevail based on a previous schema.

Enrichments batches should specify the integrationVersion so that the data is compared to the right schema.

Example

In a scenario where a technology partner wants to update its integration to add new enrichment fields, the provider can:

  • Send to Contentsquare a new integration version to be registered
  • While Contentsquare is reviewing and registering the new schema, enrichments can still be sent on the previous schema
  • When the new schema is registered eventually, the technology partner can switch to the new schema for all new enrichment by the specifying the right version in the enrichment batches
  • Potentially some customers could still decide to rely on the previous schema if needed (then the technology partner would need to keep a mapping of which customer relies on which version)

Update an enrichment

If the provider wants to update a specific enrichment, it can be done thanks to the enrichmentNumber key.

While incrementing this key represents a whole new "event" for the target session, sending an enrichment with an enrichment number already used for that session will overwrite the enrichment that was sent previously with the same enrichment number.

This is useful to update the data that was sent previously based on some new information the provider processed for the same event.

Example

In a scenario where the provider is a company that tracks phone calls, it might happen that some data related to the call gets processed after the original enrichment for this call was sent (e.g. a conversion occurred following the call but was not materialized yet the first time the call data was sent to Contentsquare).

In such a case, as it's still related to the same phone call, the provider can update the enrichment later instead of sending a whole new enrichment.