Profiles Partner Gateway API
Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.
Welcome to the official engineering documentation for the Profiles Partner Gateway!
Designed to streamline the process of survey fulfillment, our API empowers programmatic systems to efficiently manage survey plans, match them with appropriate panelists, and seamlessly redirect panelists to their designated surveys through a centralized router.
The Profiles Gateway Supply and Demand APIs provide software engineers with a robust platform to orchestrate the flow of survey plans from demand partners to supply partners and ultimately to panelists.
Demand partners leverage the API to submit survey plans detailing their requirements for market research data collection.
On the other hand, supply partners utilize the API to receive and process these survey plans, identifying and engaging the most suitable panelists to fulfill the specified criteria.
To ensure a seamless experience for panelists, our API also includes a router component responsible for accurately redirecting panelists to the corresponding surveys based on their profiles and preferences.
Survey platforms can also integrate with our router component to facilitate the seamless redirection of panelists to their designated surveys.
Authentication
The API described in this documentation uses token-based authentication in the request headers.
To access protected resources and interact with the API endpoints, clients are required to include a token (provided to them during integration) in the Authorization header of their HTTP requests.
This token serves as a secure identifier and grants authenticated access to the API’s functionality.
By adhering to this authentication mechanism, clients can securely authenticate their requests and utilize the API’s features with confidence.
- Parameter Name: x-api-key, in: header.
Demand API
The Demand API provides a streamlined interface for demand partners to submit their survey plans seamlessly.
Designed to meet the dynamic requirements of market research initiatives, this API empowers demand partners to effortlessly integrate their survey plans into the ecosystem, facilitating efficient data collection and analysis processes.
Getting Started
To begin using the Demand API, demand partners must first register for API access and obtain authentication credentials.
Once authenticated, they can programmatically submit survey plans using the provided endpoints and data payloads.
Launch a survey with a non integrated survey platform
If you need to launch a survey with a non integrated survey platform, please refer to the knowledge base for detailed instructions.
For detailed documentation on API endpoints, request and response formats, and authentication procedures, refer to the Demand API endpoints below.
API URLs:
Code samples
# You can also use wget
curl -X POST https://demand.demo.gateway.kantar.com/survey-plan \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'x-api-key: API_KEY'
POST https://demand.demo.gateway.kantar.com/survey-plan HTTP/1.1
Content-Type: application/json
Accept: application/json
const inputBody = '{
"survey_id": "demand-survey-plan-id",
"categories": [
"pets",
"wildlife conservation"
],
"country": "USA",
"locale": "es-US",
"survey_url": "https://survey-platform.com/survey/e9790abf",
"type": "interview",
"tags": [
"collects_pii",
"webcam"
],
"estimated_loi": 5,
"estimated_cr": 25,
"estimated_ir": 80,
"target_completes": 30,
"survey_platform": "Decipher",
"target_panels": [
{
"name": "lifepoints"
}
],
"pricing": {
"cpi": 150,
"unit": "fractional",
"currency": "USD"
},
"additional_qualification_count": 3,
"quotas": [
{
"id": "demand-partner-quota-id",
"qualifications": [
{
"question_id": "age",
"qualifying_answers": [
{
"start": 16,
"end": 21
}
]
}
],
"additional_qualification_count": 3,
"pricing": {
"cpi": 150,
"unit": "fractional",
"currency": "USD"
},
"target_completes": 30
}
],
"qualifications": [
{
"question_id": "age",
"qualifying_answers": [
{
"start": 16,
"end": 21
}
]
}
],
"resume_allowed": false,
"group_id": "group-id",
"project_id": "project-id",
"contact_emails": [
"email_one@email.com",
"email_two@email.com",
"email_three@email.com"
],
"finish_date": "2024-09-23T00:00:00.000Z",
"device_requirements": [
"desktop",
"mobile"
]
}';
const headers = {
'Content-Type':'application/json',
'Accept':'application/json',
'x-api-key':'API_KEY'
};
fetch('https://demand.demo.gateway.kantar.com/survey-plan',
{
method: 'POST',
body: inputBody,
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
require 'rest-client'
require 'json'
headers = {
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'x-api-key' => 'API_KEY'
}
result = RestClient.POST 'https://demand.demo.gateway.kantar.com/survey-plan',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'x-api-key': 'API_KEY'
}
r = requests.POST('https://demand.demo.gateway.kantar.com/survey-plan', headers = headers)
print(r.json())
<?php
require 'vendor/autoload.php';
$headers = array(
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'x-api-key' => 'API_KEY',
);
$client = new \GuzzleHttp\Client();
// Define array of request body.
$request_body = array();
try {
$response = $client->request('POST','https://demand.demo.gateway.kantar.com/survey-plan', array(
'headers' => $headers,
'json' => $request_body,
)
);
print_r($response->getBody()->getContents());
}
catch (\GuzzleHttp\Exception\BadResponseException $e) {
// handle exception or api errors.
print_r($e->getMessage());
}
// ...
URL obj = new URL("https://demand.demo.gateway.kantar.com/survey-plan");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
package main
import (
"bytes"
"net/http"
)
func main() {
headers := map[string][]string{
"Content-Type": []string{"application/json"},
"Accept": []string{"application/json"},
"x-api-key": []string{"API_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := http.NewRequest("POST", "https://demand.demo.gateway.kantar.com/survey-plan", data)
req.Header = headers
client := &http.Client{}
resp, err := client.Do(req)
// ...
}
POST Survey Plan
POST /survey-plan
The Create Survey Plan Endpoint enables demand partners to submit their survey plans for fulfilment by suppliers within the gateway ecosystem.
By providing essential survey details such as survey URL (on the survey platform), target panels, country, and survey type, demand partners can initiate the survey fulfilment process, facilitating data collection and analysis for market research purposes.
Usage Guidelines
- Prepare Survey Details: Gather the necessary survey details according to the schema, including survey URL from the survey platform, target qualifications, quotas and panels, country, and survey type.
- Post Survey Plan: Send a POST request, including the survey details payload.
Note
Ensure that all the survey plan details are accurately provided in the request payload, and valid authentication credentials are included for access.
A malformed request or missing authentication credentials will result in an error response from the endpoint.
Body parameter
{
"survey_id": "demand-survey-plan-id",
"categories": [
"pets",
"wildlife conservation"
],
"country": "USA",
"locale": "es-US",
"survey_url": "https://survey-platform.com/survey/e9790abf",
"type": "interview",
"tags": [
"collects_pii",
"webcam"
],
"estimated_loi": 5,
"estimated_cr": 25,
"estimated_ir": 80,
"target_completes": 30,
"survey_platform": "Decipher",
"target_panels": [
{
"name": "lifepoints"
}
],
"pricing": {
"cpi": 150,
"unit": "fractional",
"currency": "USD"
},
"additional_qualification_count": 3,
"quotas": [
{
"id": "demand-partner-quota-id",
"qualifications": [
{
"question_id": "age",
"qualifying_answers": [
{
"start": 16,
"end": 21
}
]
}
],
"additional_qualification_count": 3,
"pricing": {
"cpi": 150,
"unit": "fractional",
"currency": "USD"
},
"target_completes": 30
}
],
"qualifications": [
{
"question_id": "age",
"qualifying_answers": [
{
"start": 16,
"end": 21
}
]
}
],
"resume_allowed": false,
"group_id": "group-id",
"project_id": "project-id",
"contact_emails": [
"email_one@email.com",
"email_two@email.com",
"email_three@email.com"
],
"finish_date": "2024-09-23T00:00:00.000Z",
"device_requirements": [
"desktop",
"mobile"
]
}
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
body | body | SurveyPlan | true | Request body for creating a new survey plan |
Example responses
201 Response
{
"id": "ppg-survey-plan-id"
}
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
201 | Created | Created Survey Plan | CreateSurveyPlanResponse |
400 | Bad Request | Validation error | ValidationError |
401 | Unauthorized | Access token is missing or invalid | Error |
500 | Internal Server Error | Unexpected error | Error |
Code samples
# You can also use wget
curl -X GET https://demand.demo.gateway.kantar.com/survey-plans/{id} \
-H 'Accept: application/json' \
-H 'x-api-key: API_KEY'
GET https://demand.demo.gateway.kantar.com/survey-plans/{id} HTTP/1.1
Accept: application/json
const headers = {
'Accept':'application/json',
'x-api-key':'API_KEY'
};
fetch('https://demand.demo.gateway.kantar.com/survey-plans/{id}',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json',
'x-api-key' => 'API_KEY'
}
result = RestClient.GET 'https://demand.demo.gateway.kantar.com/survey-plans/{id}',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json',
'x-api-key': 'API_KEY'
}
r = requests.GET('https://demand.demo.gateway.kantar.com/survey-plans/{id}', headers = headers)
print(r.json())
<?php
require 'vendor/autoload.php';
$headers = array(
'Accept' => 'application/json',
'x-api-key' => 'API_KEY',
);
$client = new \GuzzleHttp\Client();
// Define array of request body.
$request_body = array();
try {
$response = $client->request('GET','https://demand.demo.gateway.kantar.com/survey-plans/{id}', array(
'headers' => $headers,
'json' => $request_body,
)
);
print_r($response->getBody()->getContents());
}
catch (\GuzzleHttp\Exception\BadResponseException $e) {
// handle exception or api errors.
print_r($e->getMessage());
}
// ...
URL obj = new URL("https://demand.demo.gateway.kantar.com/survey-plans/{id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
package main
import (
"bytes"
"net/http"
)
func main() {
headers := map[string][]string{
"Accept": []string{"application/json"},
"x-api-key": []string{"API_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := http.NewRequest("GET", "https://demand.demo.gateway.kantar.com/survey-plans/{id}", data)
req.Header = headers
client := &http.Client{}
resp, err := client.Do(req)
// ...
}
GET Survey Plan
GET /survey-plans/{id}
The Get Survey Plan Endpoint enables demand partners to see how many completes have been done for a Survey Plan
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
id | path | string | true | The ID of the survey plan that responded upon its creation |
Example responses
200 Response
{
"survey_plan": {
"id": "ppg-survey-plan-id",
"categories": [
"pets",
"wildlife conservation"
],
"country": "USA",
"locale": "es-US",
"survey_url": "https://survey-platform.com/survey/e9790abf",
"type": "interview",
"tags": [
"collects_pii",
"webcam"
],
"estimated_loi": 5,
"estimated_cr": 25,
"estimated_ir": 80,
"target_completes": 30,
"survey_platform": "Decipher",
"status": "OPEN",
"target_panels": [
{
"name": "lifepoints"
}
],
"pricing": {
"cpi": 150,
"unit": "fractional",
"currency": "USD"
},
"additional_qualification_count": 3,
"quotas": [
{
"id": "demand-partner-quota-id",
"qualifications": [
{
"question_id": "age",
"qualifying_answers": [
{
"start": 16,
"end": 21
}
]
}
],
"additional_qualification_count": 3,
"pricing": {
"cpi": 150,
"unit": "fractional",
"currency": "USD"
},
"target_completes": 30,
"status": "OPEN"
}
],
"qualifications": [
{
"question_id": "age",
"qualifying_answers": [
{
"start": 16,
"end": 21
}
]
}
],
"resume_allowed": false,
"group_id": "group-id",
"project_id": "project-id",
"contact_emails": [
"email_one@email.com",
"email_two@email.com",
"email_three@email.com"
],
"finish_date": "2024-09-23T00:00:00.000Z",
"device_requirements": [
"desktop",
"mobile"
]
},
"available_completes": {
"survey": 30,
"quotas": {
"quotaId1": 50,
"quotaId2": 60
}
},
"survey_performance": {
"completes": 2,
"failures": 8,
"status_metrics": {
"property1": {
"COMPLETED": 2,
"TERMINATED": 5,
"REJECTED": 2,
"DISQUALIFIED": 1
},
"property2": {
"COMPLETED": 2,
"TERMINATED": 5,
"REJECTED": 2,
"DISQUALIFIED": 1
}
}
}
}
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | SurveyPlan with available completes | GetSurveyPlanResponse |
400 | Bad Request | Validation error | ValidationError |
401 | Unauthorized | Access token is missing or invalid | Error |
500 | Internal Server Error | Unexpected error | Error |
Code samples
# You can also use wget
curl -X PATCH https://demand.demo.gateway.kantar.com/survey-plans/{id} \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'x-api-key: API_KEY'
PATCH https://demand.demo.gateway.kantar.com/survey-plans/{id} HTTP/1.1
Content-Type: application/json
Accept: application/json
const inputBody = '{
"status": "OPEN"
}';
const headers = {
'Content-Type':'application/json',
'Accept':'application/json',
'x-api-key':'API_KEY'
};
fetch('https://demand.demo.gateway.kantar.com/survey-plans/{id}',
{
method: 'PATCH',
body: inputBody,
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
require 'rest-client'
require 'json'
headers = {
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'x-api-key' => 'API_KEY'
}
result = RestClient.PATCH 'https://demand.demo.gateway.kantar.com/survey-plans/{id}',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'x-api-key': 'API_KEY'
}
r = requests.PATCH('https://demand.demo.gateway.kantar.com/survey-plans/{id}', headers = headers)
print(r.json())
<?php
require 'vendor/autoload.php';
$headers = array(
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'x-api-key' => 'API_KEY',
);
$client = new \GuzzleHttp\Client();
// Define array of request body.
$request_body = array();
try {
$response = $client->request('PATCH','https://demand.demo.gateway.kantar.com/survey-plans/{id}', array(
'headers' => $headers,
'json' => $request_body,
)
);
print_r($response->getBody()->getContents());
}
catch (\GuzzleHttp\Exception\BadResponseException $e) {
// handle exception or api errors.
print_r($e->getMessage());
}
// ...
URL obj = new URL("https://demand.demo.gateway.kantar.com/survey-plans/{id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("PATCH");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
package main
import (
"bytes"
"net/http"
)
func main() {
headers := map[string][]string{
"Content-Type": []string{"application/json"},
"Accept": []string{"application/json"},
"x-api-key": []string{"API_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := http.NewRequest("PATCH", "https://demand.demo.gateway.kantar.com/survey-plans/{id}", data)
req.Header = headers
client := &http.Client{}
resp, err := client.Do(req)
// ...
}
PATCH Survey Plan
PATCH /survey-plans/{id}
The Edit Survey Plan Endpoint enables demand partners to submit allowed edits on existing survey plans.
Usage Guidelines
- Prepare Survey Updates: Ensure your updates are compliant with the schema. New updates will be extended based on the schema. Make sure your updates align with the existing survey details.
- Post Survey Plan: Send a PATCH request including the survey updates payload.
Note
Ensure that all the survey plan updates are accurately provided in the request payload and that valid authentication credentials are included for access. A malformed request or missing authentication credentials will result in an error response from the endpoint.
Allowed Properties for Updates:
- Status
Body parameter
{
"status": "OPEN"
}
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
id | path | string | true | The ID of the survey plan that responded upon its creation |
body | body | EditSurveyPlanRequest | true | Request body to update a survey plan. |
Example responses
200 Response
{
"id": "ppg-survey-plan-id",
"message": "string"
}
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | The response body for updating the survey plan | EditSurveyPlanResponse |
400 | Bad Request | Validation error | ValidationError |
401 | Unauthorized | Access token is missing or invalid | Error |
404 | Not Found | Not Found | Error |
500 | Internal Server Error | Unexpected error | Error |
Code samples
# You can also use wget
curl -X DELETE https://demand.demo.gateway.kantar.com/survey-plans/{id} \
-H 'Accept: application/json' \
-H 'x-api-key: API_KEY'
DELETE https://demand.demo.gateway.kantar.com/survey-plans/{id} HTTP/1.1
Accept: application/json
const headers = {
'Accept':'application/json',
'x-api-key':'API_KEY'
};
fetch('https://demand.demo.gateway.kantar.com/survey-plans/{id}',
{
method: 'DELETE',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json',
'x-api-key' => 'API_KEY'
}
result = RestClient.DELETE 'https://demand.demo.gateway.kantar.com/survey-plans/{id}',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json',
'x-api-key': 'API_KEY'
}
r = requests.DELETE('https://demand.demo.gateway.kantar.com/survey-plans/{id}', headers = headers)
print(r.json())
<?php
require 'vendor/autoload.php';
$headers = array(
'Accept' => 'application/json',
'x-api-key' => 'API_KEY',
);
$client = new \GuzzleHttp\Client();
// Define array of request body.
$request_body = array();
try {
$response = $client->request('DELETE','https://demand.demo.gateway.kantar.com/survey-plans/{id}', array(
'headers' => $headers,
'json' => $request_body,
)
);
print_r($response->getBody()->getContents());
}
catch (\GuzzleHttp\Exception\BadResponseException $e) {
// handle exception or api errors.
print_r($e->getMessage());
}
// ...
URL obj = new URL("https://demand.demo.gateway.kantar.com/survey-plans/{id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("DELETE");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
package main
import (
"bytes"
"net/http"
)
func main() {
headers := map[string][]string{
"Accept": []string{"application/json"},
"x-api-key": []string{"API_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := http.NewRequest("DELETE", "https://demand.demo.gateway.kantar.com/survey-plans/{id}", data)
req.Header = headers
client := &http.Client{}
resp, err := client.Do(req)
// ...
}
DELETE Survey Plan
DELETE /survey-plans/{id}
Enables demand partners to delete a Survey Plan. We are allowed to delete it only if it’s closed and there are no sessions in progress.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
id | path | string | true | The ID of the survey plan that responded upon its creation |
Example responses
400 Response
{
"code": "string",
"message": "string",
"details": [
{
"constraint": "string",
"field": "string",
"message": "string"
}
]
}
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
204 | No Content | Survey Plan deleted successfully | None |
400 | Bad Request | Validation error | ValidationError |
401 | Unauthorized | Access token is missing or invalid | Error |
404 | Not Found | Not Found | Error |
500 | Internal Server Error | Unexpected error | Error |
Code samples
# You can also use wget
curl -X PATCH https://demand.demo.gateway.kantar.com/survey-plans/{id}/quotas/{quotaId} \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'x-api-key: API_KEY'
PATCH https://demand.demo.gateway.kantar.com/survey-plans/{id}/quotas/{quotaId} HTTP/1.1
Content-Type: application/json
Accept: application/json
const inputBody = '{
"status": "OPEN"
}';
const headers = {
'Content-Type':'application/json',
'Accept':'application/json',
'x-api-key':'API_KEY'
};
fetch('https://demand.demo.gateway.kantar.com/survey-plans/{id}/quotas/{quotaId}',
{
method: 'PATCH',
body: inputBody,
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
require 'rest-client'
require 'json'
headers = {
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'x-api-key' => 'API_KEY'
}
result = RestClient.PATCH 'https://demand.demo.gateway.kantar.com/survey-plans/{id}/quotas/{quotaId}',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'x-api-key': 'API_KEY'
}
r = requests.PATCH('https://demand.demo.gateway.kantar.com/survey-plans/{id}/quotas/{quotaId}', headers = headers)
print(r.json())
<?php
require 'vendor/autoload.php';
$headers = array(
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'x-api-key' => 'API_KEY',
);
$client = new \GuzzleHttp\Client();
// Define array of request body.
$request_body = array();
try {
$response = $client->request('PATCH','https://demand.demo.gateway.kantar.com/survey-plans/{id}/quotas/{quotaId}', array(
'headers' => $headers,
'json' => $request_body,
)
);
print_r($response->getBody()->getContents());
}
catch (\GuzzleHttp\Exception\BadResponseException $e) {
// handle exception or api errors.
print_r($e->getMessage());
}
// ...
URL obj = new URL("https://demand.demo.gateway.kantar.com/survey-plans/{id}/quotas/{quotaId}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("PATCH");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
package main
import (
"bytes"
"net/http"
)
func main() {
headers := map[string][]string{
"Content-Type": []string{"application/json"},
"Accept": []string{"application/json"},
"x-api-key": []string{"API_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := http.NewRequest("PATCH", "https://demand.demo.gateway.kantar.com/survey-plans/{id}/quotas/{quotaId}", data)
req.Header = headers
client := &http.Client{}
resp, err := client.Do(req)
// ...
}
PATCH Survey Plan Quota
PATCH /survey-plans/{id}/quotas/{quotaId}
The Edit Survey Plan Quota Endpoint enables demand partners to submit allowed edits on existing survey plan’s quotas.
Usage Guidelines
- Prepare Survey Quota Updates: Ensure your updates are compliant with the schema. New updates will be extended based on the schema. Make sure your updates align with the existing survey’s quota details.
- Post Survey Plan: Send a PATCH request including the survey quota updates payload.
Note
Ensure that all the survey plan updates are accurately provided in the request payload and that valid authentication credentials are included for access. A malformed request or missing authentication credentials will result in an error response from the endpoint.
Allowed Properties for Updates:
- Status
Body parameter
{
"status": "OPEN"
}
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
id | path | string | true | The ID of the survey plan that responded upon its creation |
quotaId | path | string | true | Unique identifier for the survey plan quota. |
body | body | EditQuotaRequest | true | Request body to update a survey plan’s quota. |
Example responses
200 Response
{
"id": "ppg-survey-plan-id",
"survey_plan_status": "OPEN",
"message": "string"
}
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | The response body for updating the survey plan’s quota | EditQuotaResponse |
400 | Bad Request | Validation error | ValidationError |
401 | Unauthorized | Access token is missing or invalid | Error |
404 | Not Found | Not Found | Error |
500 | Internal Server Error | Unexpected error | Error |
Code samples
# You can also use wget
curl -X GET https://demand.demo.gateway.kantar.com/targeting-attributes?country=string \
-H 'Accept: application/json' \
-H 'x-api-key: API_KEY'
GET https://demand.demo.gateway.kantar.com/targeting-attributes?country=string HTTP/1.1
Accept: application/json
const headers = {
'Accept':'application/json',
'x-api-key':'API_KEY'
};
fetch('https://demand.demo.gateway.kantar.com/targeting-attributes?country=string',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json',
'x-api-key' => 'API_KEY'
}
result = RestClient.GET 'https://demand.demo.gateway.kantar.com/targeting-attributes',
params: {
'country' => 'string'
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json',
'x-api-key': 'API_KEY'
}
r = requests.GET('https://demand.demo.gateway.kantar.com/targeting-attributes', params={
'country': 'string'
}, headers = headers)
print(r.json())
<?php
require 'vendor/autoload.php';
$headers = array(
'Accept' => 'application/json',
'x-api-key' => 'API_KEY',
);
$client = new \GuzzleHttp\Client();
// Define array of request body.
$request_body = array();
try {
$response = $client->request('GET','https://demand.demo.gateway.kantar.com/targeting-attributes', array(
'headers' => $headers,
'json' => $request_body,
)
);
print_r($response->getBody()->getContents());
}
catch (\GuzzleHttp\Exception\BadResponseException $e) {
// handle exception or api errors.
print_r($e->getMessage());
}
// ...
URL obj = new URL("https://demand.demo.gateway.kantar.com/targeting-attributes?country=string");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
package main
import (
"bytes"
"net/http"
)
func main() {
headers := map[string][]string{
"Accept": []string{"application/json"},
"x-api-key": []string{"API_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := http.NewRequest("GET", "https://demand.demo.gateway.kantar.com/targeting-attributes", data)
req.Header = headers
client := &http.Client{}
resp, err := client.Do(req)
// ...
}
GET Targeting Attributes
GET /targeting-attributes
Retrieve the list of valid targeting to build a valid survey plan.
Note
To fetch attributes for a particular country, add a ‘country’ query parameter to the URL, specifying the country in ISO 3166-1 alpha-3 format as its value. If no country is provided, all attribute questions will be displayed.
Attributes that do not have a supported country specified, they are available for all countries.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
country | query | string | true | Get the targeting attributes for the specified country, make sure to use a valid ISO3166-1 alpha3 country code. |
Example responses
200 Response
{
"targeting_attributes": [
{
"id": "age",
"text": "What is your age?",
"answers_type": "range",
"range_limits": {
"start": 16,
"end": 100
}
},
{
"id": "sex",
"text": "What do you most closely identify as?",
"answer_type": "single_choice",
"supported_countries": [
"USA",
"GBR"
],
"answers": [
{
"id": "male",
"text": "Male"
},
{
"id": "female",
"text": "Female"
}
]
}
]
}
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | List of targeting questions | TargetingAttributeResponse |
401 | Unauthorized | Access token is missing or invalid | Error |
500 | Internal Server Error | Unexpected error | Error |
Code samples
# You can also use wget
curl -X GET https://demand.demo.gateway.kantar.com/targeting-panels \
-H 'Accept: application/json' \
-H 'x-api-key: API_KEY'
GET https://demand.demo.gateway.kantar.com/targeting-panels HTTP/1.1
Accept: application/json
const headers = {
'Accept':'application/json',
'x-api-key':'API_KEY'
};
fetch('https://demand.demo.gateway.kantar.com/targeting-panels',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json',
'x-api-key' => 'API_KEY'
}
result = RestClient.GET 'https://demand.demo.gateway.kantar.com/targeting-panels',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json',
'x-api-key': 'API_KEY'
}
r = requests.GET('https://demand.demo.gateway.kantar.com/targeting-panels', headers = headers)
print(r.json())
<?php
require 'vendor/autoload.php';
$headers = array(
'Accept' => 'application/json',
'x-api-key' => 'API_KEY',
);
$client = new \GuzzleHttp\Client();
// Define array of request body.
$request_body = array();
try {
$response = $client->request('GET','https://demand.demo.gateway.kantar.com/targeting-panels', array(
'headers' => $headers,
'json' => $request_body,
)
);
print_r($response->getBody()->getContents());
}
catch (\GuzzleHttp\Exception\BadResponseException $e) {
// handle exception or api errors.
print_r($e->getMessage());
}
// ...
URL obj = new URL("https://demand.demo.gateway.kantar.com/targeting-panels");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
package main
import (
"bytes"
"net/http"
)
func main() {
headers := map[string][]string{
"Accept": []string{"application/json"},
"x-api-key": []string{"API_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := http.NewRequest("GET", "https://demand.demo.gateway.kantar.com/targeting-panels", data)
req.Header = headers
client := &http.Client{}
resp, err := client.Do(req)
// ...
}
GET Available Panels
GET /targeting-panels
The Retrieve Targeting Panels Endpoint provides demand partners with access to the configuration details of various panels available within the gateway ecosystem. This endpoint is essential for partners to understand the specific characteristics and requirements of each panel, helping to streamline the process of survey planning and execution.
Usage Guidelines
- Query Panel Configurations: Use this endpoint to request detailed information about the panels, including supported countries, available locales, and currency information. This information aids in selecting the appropriate panels for survey targeting.
- Receive Configurations: The response includes comprehensive details about each panel, such as panel name, supported countries, locales, and associated currency, which are crucial for preparing accurate and effective survey plans.
Note
Ensure that the request to this endpoint is made with valid authentication credentials to access the data. Incorrect or missing credentials will lead to an authentication error.
This endpoint serves read-only information and does not accept modifications to the panel configurations.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
country | query | string | false | Get the targeting panels for the specified country, make sure to use a valid ISO3166-1 alpha3 country code. |
panel | query | string | false | Get the targeting panels configuration for the specified panel. |
Example responses
200 Response
{
"panel1": {
"GBR": {
"locales": [
"en-GB"
],
"currency": "GBP"
},
"USA": {
"locales": [
"en-US",
"es-US"
],
"currency": "USD"
}
},
"panel2": {
"ITA": {
"locales": [
"it-IT"
],
"currency": "EUR"
},
"USA": {
"locales": [
"en-US",
"es-US"
],
"currency": "USD"
}
},
"panel3": {
"CAN": {
"locales": [
"fr-CA",
"en-CA"
],
"currency": "CAD"
},
"CHE": {
"locales": [
"de-CH",
"fr-CH",
"it-CH"
],
"currency": "CHF"
}
}
}
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Configurations for targeting panels | TargetingPanelsResponse |
401 | Unauthorized | Access token is missing or invalid | Error |
500 | Internal Server Error | Unexpected error | Error |
Supply API
The Supply API offers a comprehensive solution for supply partners to efficiently retrieve survey plan updates and synchronize data seamlessly.
Designed to streamline the process of data retrieval and acknowledgment, this API empowers supply partners to poll the system periodically for the latest updates and acknowledge processed data with ease.
Key Features
Real-time Data Updates:
Supply partners can retrieve survey plan updates in real-time by polling the API at regular intervals, ensuring access to the latest information for effective decision-making.
Polling Mechanism:
The API supports a robust polling mechanism, allowing supply partners to query the system periodically for updates. Polling intervals can be customized to suit the specific requirements of supply partners.
Acknowledgment Endpoint:
A dedicated acknowledgment endpoint enables supply partners to acknowledge the latest processed survey plan ID before initiating the next poll, ensuring data integrity and synchronization.
Asynchronous Processing:
The API architecture is designed for asynchronous processing, enabling supply partners to retrieve updates efficiently without impacting system performance.
Getting Started
To begin using the Supply API, supply partners must first register for API access and obtain authentication credentials.
Once authenticated, they can initiate polling requests to retrieve survey plan updates and acknowledge processed data using the provided endpoints.
For detailed documentation on API endpoints, request and response formats, polling intervals, and acknowledgment procedures, refer to the Supply API documentation below.
API URLs:
Code samples
# You can also use wget
curl -X GET https://supply.demo.gateway.kantar.com/surveys \
-H 'Accept: application/json' \
-H 'x-api-key: API_KEY'
GET https://supply.demo.gateway.kantar.com/surveys HTTP/1.1
Accept: application/json
const headers = {
'Accept':'application/json',
'x-api-key':'API_KEY'
};
fetch('https://supply.demo.gateway.kantar.com/surveys',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json',
'x-api-key' => 'API_KEY'
}
result = RestClient.GET 'https://supply.demo.gateway.kantar.com/surveys',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json',
'x-api-key': 'API_KEY'
}
r = requests.GET('https://supply.demo.gateway.kantar.com/surveys', headers = headers)
print(r.json())
<?php
require 'vendor/autoload.php';
$headers = array(
'Accept' => 'application/json',
'x-api-key' => 'API_KEY',
);
$client = new \GuzzleHttp\Client();
// Define array of request body.
$request_body = array();
try {
$response = $client->request('GET','https://supply.demo.gateway.kantar.com/surveys', array(
'headers' => $headers,
'json' => $request_body,
)
);
print_r($response->getBody()->getContents());
}
catch (\GuzzleHttp\Exception\BadResponseException $e) {
// handle exception or api errors.
print_r($e->getMessage());
}
// ...
URL obj = new URL("https://supply.demo.gateway.kantar.com/surveys");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
package main
import (
"bytes"
"net/http"
)
func main() {
headers := map[string][]string{
"Accept": []string{"application/json"},
"x-api-key": []string{"API_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := http.NewRequest("GET", "https://supply.demo.gateway.kantar.com/surveys", data)
req.Header = headers
client := &http.Client{}
resp, err := client.Do(req)
// ...
}
GET Retrieve Survey Updates
GET /surveys
The Retrieve Survey Plan Updates Endpoint allows suppliers to retrieve the latest survey plan updates from the system, as well as newly created survey plans.
Suppliers are required to poll this endpoint regularly, typically every 10-15 seconds, to fetch a list of survey plans that have been updated within the specified period.
This enables suppliers to stay synchronized with the latest survey requirements and ensure timely fulfilment.
Suppliers will then proceed to find the correct panelists for fulfilment, and use the Session Router to create sessions for those panelists.
Usage Guidelines
- Poll Endpoint Regularly: Suppliers should poll the endpoint at regular intervals, typically every 10-15 seconds, to retrieve the latest survey plan updates..
- Process Survey Plan Updates: Upon receiving the list of updated survey plans, suppliers should process the information and take appropriate actions, such as assigning panelists or initiating survey activities.
- Send Acknowledgment: After processing the survey plan updates, suppliers must send an acknowledgment (ack) to the confirmation endpoint to indicate the last record read and prepare for the next poll cycle.
- Store Entry Link: Store the received entry link per survey plan, as this will be used to create the panelist session in the router.
Note
Suppliers should ensure that they handle the retrieved survey plan updates appropriately and acknowledge the last record read to maintain synchronization with the system.
Example responses
200 Response
[
{
"version": "3052896:1711272468123",
"ack_id": 1711272468123,
"survey_session_creation_url": "https://gateway.kantar.com/panels/123456/session/34829348329d893",
"survey_plan": {
"id": "panel-survey-plan-id",
"categories": [
"pets",
"wildlife conservation"
],
"country": "USA",
"locale": "es-US",
"type": "interview",
"tags": [
"collects_pii",
"webcam"
],
"loi": 5,
"cr": 25,
"ir": 80,
"available_completes": 30,
"pricing": {
"cpi": 150,
"unit": "fractional",
"currency": "USD"
},
"additional_qualification_count": 3,
"status": "OPEN",
"quotas": [
{
"id": "demand-partner-quota-id",
"available_completes": 5,
"status": "OPEN",
"qualifications": [
{
"question_id": "age",
"qualifying_answers": [
"16-40"
]
}
],
"additional_qualification_count": 3,
"pricing": {
"cpi": 150,
"unit": "fractional",
"currency": "USD"
}
}
],
"qualifications": [
{
"question_id": "age",
"qualifying_answers": [
"16-40"
]
}
],
"resume_allowed": false,
"group_id": "group-id",
"project_id": "project-id",
"contact_emails": [
"email_one@email.com",
"email_two@email.com",
"email_three@email.com"
],
"finish_date": "2024-09-23T00:00:00.000Z",
"device_requirements": [
"desktop",
"mobile"
]
}
}
]
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | List of all available survey plan updates with changes since the last ack request | SurveyPlanUpdatesResponse |
400 | Bad Request | Bad Request | Error |
401 | Unauthorized | Access token is missing or invalid | Error |
500 | Internal Server Error | Unexpected error | Error |
Code samples
# You can also use wget
curl -X POST https://supply.demo.gateway.kantar.com/surveys/ack \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'x-api-key: API_KEY'
POST https://supply.demo.gateway.kantar.com/surveys/ack HTTP/1.1
Content-Type: application/json
Accept: application/json
const inputBody = '{
"ack_id": 1711272468123
}';
const headers = {
'Content-Type':'application/json',
'Accept':'application/json',
'x-api-key':'API_KEY'
};
fetch('https://supply.demo.gateway.kantar.com/surveys/ack',
{
method: 'POST',
body: inputBody,
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
require 'rest-client'
require 'json'
headers = {
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'x-api-key' => 'API_KEY'
}
result = RestClient.POST 'https://supply.demo.gateway.kantar.com/surveys/ack',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'x-api-key': 'API_KEY'
}
r = requests.POST('https://supply.demo.gateway.kantar.com/surveys/ack', headers = headers)
print(r.json())
<?php
require 'vendor/autoload.php';
$headers = array(
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'x-api-key' => 'API_KEY',
);
$client = new \GuzzleHttp\Client();
// Define array of request body.
$request_body = array();
try {
$response = $client->request('POST','https://supply.demo.gateway.kantar.com/surveys/ack', array(
'headers' => $headers,
'json' => $request_body,
)
);
print_r($response->getBody()->getContents());
}
catch (\GuzzleHttp\Exception\BadResponseException $e) {
// handle exception or api errors.
print_r($e->getMessage());
}
// ...
URL obj = new URL("https://supply.demo.gateway.kantar.com/surveys/ack");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
package main
import (
"bytes"
"net/http"
)
func main() {
headers := map[string][]string{
"Content-Type": []string{"application/json"},
"Accept": []string{"application/json"},
"x-api-key": []string{"API_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := http.NewRequest("POST", "https://supply.demo.gateway.kantar.com/surveys/ack", data)
req.Header = headers
client := &http.Client{}
resp, err := client.Do(req)
// ...
}
POST Confirm Receipt
POST /surveys/ack
The Confirm Receipt of Survey Plan Updates Endpoint enables suppliers to acknowledge the receipt of survey plan updates from the system, including newly created survey plans.
After processing the retrieved survey plan updates, suppliers must acknowledge each update by sending an acknowledgment (ack) containing the ID of the latest survey plan update processed.
The system determines the latest survey plan update based on the highest ID or timestamp, ensuring synchronization with the supplier’s processing.
Usage Guidelines
- Process Survey Plan Updates: After retrieving survey plan updates from the system, suppliers should process and store the received plan and perform or prepared for the necessary actions, such as sampling..
- Determine Latest Update ID: Suppliers should determine the ID of the latest survey plan update processed, typically by selecting the highest survey plan ID or the most recent timestamp.
- Send Acknowledgment: Send a POST request to the confirmation endpoint, including the ID of the latest survey plan update processed in the request payload.
- Maintain Synchronization: By acknowledging the latest update, suppliers ensure synchronization with the system and prepare for subsequent poll cycles, which will only contain updates after the acked ID.
Note
Suppliers should ensure that they accurately determine the ID of the latest survey plan update processed to maintain synchronization with the system.
Failure to do so may cause the supply API to resend the same survey plan updates in subsequent poll cycles.
Body parameter
{
"ack_id": 1711272468123
}
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
body | body | SurveyPlanUpdateAck | true | Request body for acking a survey plan update |
Example responses
400 Response
{
"code": "string",
"message": "string",
"success": true
}
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
204 | No Content | Latest Survey Plan ID was acked | None |
400 | Bad Request | Bad Request | Error |
401 | Unauthorized | Access token is missing or invalid | Error |
500 | Internal Server Error | Unexpected error | Error |
Session Router
The Sessions Router serves as a central hub for managing panelist sessions and survey outcomes within the market research ecosystem.
Suppliers use this router to obtain entry URLs for their panelists and submit relevant information to the system, while survey platforms interact with the router to submit survey outcomes and receive the final session redirect URLs.
Key Features
Panelist Entry URLs:
Suppliers can retrieve unique entry URLs for their panelists through the Sessions Router, enabling secure access to the survey session.
Panelist information Endpoint:
The URL provided in the survey plan via the supply-api allows suppliers to submit panelist information, including demographic data and other custom data, while obtaining their entry link.
Outcome Submission:
Survey platforms use the Sessions Router to submit the final survey outcomes, including completion status, facilitating real-time data collection and analysis.
Redirect URLs:
Upon submission of survey outcomes, survey platforms receive redirect URLs from the Sessions Router, enabling seamless redirection of panelists back to their designated destinations based on survey completion status.
Getting Started
To begin using the Sessions Router, suppliers and survey platforms must first register for API access and obtain authentication credentials. Once authenticated, they can interact with the router to obtain entry URLs, submit panelist information, submit survey outcomes, and receive redirect URLs as needed.
For detailed documentation on API endpoints, request and response formats, authentication procedures, and usage guidelines, refer to the Sessions Router documentation below.
API URLs:
Code samples
# You can also use wget
curl -X POST https://router.demo.gateway.kantar.com/panels/{panelId}/session/{token} \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'x-api-key: API_KEY'
POST https://router.demo.gateway.kantar.com/panels/{panelId}/session/{token} HTTP/1.1
Content-Type: application/json
Accept: application/json
const inputBody = '{
"panelist_id": "123456",
"target_quota_id": "1",
"custom_panel_data": {
"internal_id": "213"
},
"panelist_profile": {
"age": 22,
"sex": "male",
"pets": "1|2|4|7"
}
}';
const headers = {
'Content-Type':'application/json',
'Accept':'application/json',
'x-api-key':'API_KEY'
};
fetch('https://router.demo.gateway.kantar.com/panels/{panelId}/session/{token}',
{
method: 'POST',
body: inputBody,
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
require 'rest-client'
require 'json'
headers = {
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'x-api-key' => 'API_KEY'
}
result = RestClient.POST 'https://router.demo.gateway.kantar.com/panels/{panelId}/session/{token}',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'x-api-key': 'API_KEY'
}
r = requests.POST('https://router.demo.gateway.kantar.com/panels/{panelId}/session/{token}', headers = headers)
print(r.json())
<?php
require 'vendor/autoload.php';
$headers = array(
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'x-api-key' => 'API_KEY',
);
$client = new \GuzzleHttp\Client();
// Define array of request body.
$request_body = array();
try {
$response = $client->request('POST','https://router.demo.gateway.kantar.com/panels/{panelId}/session/{token}', array(
'headers' => $headers,
'json' => $request_body,
)
);
print_r($response->getBody()->getContents());
}
catch (\GuzzleHttp\Exception\BadResponseException $e) {
// handle exception or api errors.
print_r($e->getMessage());
}
// ...
URL obj = new URL("https://router.demo.gateway.kantar.com/panels/{panelId}/session/{token}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
package main
import (
"bytes"
"net/http"
)
func main() {
headers := map[string][]string{
"Content-Type": []string{"application/json"},
"Accept": []string{"application/json"},
"x-api-key": []string{"API_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := http.NewRequest("POST", "https://router.demo.gateway.kantar.com/panels/{panelId}/session/{token}", data)
req.Header = headers
client := &http.Client{}
resp, err := client.Do(req)
// ...
}
POST Create Session
POST /panels/{panelId}/session/{token}
To be used by Suppliers
The Create Session Endpoint allows suppliers to initiate session creation by posting panelist information into it.
They will obtain this URL, with a correct identifier for the selected survey, from the provided survey plan received on the Supply API.
Upon successful submission, the endpoint generates a final entry link for the panelist, enabling access to the market research ecosystem.
Usage Guidelines
- Obtain session creation URL: Get the session creation link from the survey plan using the supply API.
- Obtain Panelist Information: Gather the necessary panelist information, including demographic data and custom data, to be submitted to the Create Session Endpoint.
- Post Panelist Information: Send a POST request to the provided endpoint URL `/panels/{panelId}/session/{token}`, including the panelist information payload and valid supplier authentication credentials.
- Receive Final Entry Link: Upon successful submission, the endpoint generates a final entry link for the panelist, which can be used to access the survey.
Note
Ensure that the panelist information is accurately formatted and includes all required fields as specified in the API documentation.
Body parameter
{
"panelist_id": "123456",
"target_quota_id": "1",
"custom_panel_data": {
"internal_id": "213"
},
"panelist_profile": {
"age": 22,
"sex": "male",
"pets": "1|2|4|7"
}
}
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
panelId | path | string | true | The id of the panelist platform. |
token | path | string | true | Token used to identify the session. |
body | body | SurveySession | true | Request body to create a survey session. |
Example responses
200 Response
{
"url": "https://session.kantar.com/sessions/start/43ac6dbbecbf85927db36f02b57c2958"
}
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Created Session | CreateSurveySessionResponse |
400 | Bad Request | Validation error | ValidationError |
401 | Unauthorized | Access token is missing or invalid | Error |
500 | Internal Server Error | Unexpected error | Error |
Code samples
# You can also use wget
curl -X GET https://router.demo.gateway.kantar.com/sessions/{token} \
-H 'Accept: application/json' \
-H 'x-api-key: API_KEY'
GET https://router.demo.gateway.kantar.com/sessions/{token} HTTP/1.1
Accept: application/json
const headers = {
'Accept':'application/json',
'x-api-key':'API_KEY'
};
fetch('https://router.demo.gateway.kantar.com/sessions/{token}',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json',
'x-api-key' => 'API_KEY'
}
result = RestClient.get 'https://router.demo.gateway.kantar.com/sessions/{token}',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json',
'x-api-key': 'API_KEY'
}
r = requests.get('https://router.demo.gateway.kantar.com/sessions/{token}', headers = headers)
print(r.json())
<?php
require 'vendor/autoload.php';
$headers = array(
'Accept' => 'application/json',
'x-api-key' => 'API_KEY',
);
$client = new \GuzzleHttp\Client();
// Define array of request body.
$request_body = array();
try {
$response = $client->request('GET','https://router.demo.gateway.kantar.com/sessions/{token}', array(
'headers' => $headers,
'json' => $request_body,
)
);
print_r($response->getBody()->getContents());
}
catch (\GuzzleHttp\Exception\BadResponseException $e) {
// handle exception or api errors.
print_r($e->getMessage());
}
// ...
URL obj = new URL("https://router.demo.gateway.kantar.com/sessions/{token}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
package main
import (
"bytes"
"net/http"
)
func main() {
headers := map[string][]string{
"Accept": []string{"application/json"},
"x-api-key": []string{"API_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := http.NewRequest("GET", "https://router.demo.gateway.kantar.com/sessions/{token}", data)
req.Header = headers
client := &http.Client{}
resp, err := client.Do(req)
// ...
}
GET Retrieve Session
GET /sessions/{token}
To be used by Survey Platforms
The Retrieve Session Endpoint enables survey platforms to retrieve additional details of a session by providing the session token obtained from the redirect URL query string parameters.
By including their authentication credentials and the session token, survey platforms can access essential information such as panelist demographics, survey details and custom metadata, facilitating secure data collection in an easy to understand JSON format.
Usage Guidelines
- Extract Session Token: Extract the session token from the redirect URL query string parameter `t`, received after a panelist starts a survey.
- Post Session Token: Send a GET request to the session endpoint, including the extracted session token and valid survey platform authentication credentials.
- Receive Session Information: Upon successful authentication and submission, the endpoint returns detailed session information, providing insights into panelist demographics, survey details and custom metadata in JSON format.
- Store Session ID: The returned session information will contain a session ID, which should be stored for later use at the end of the survey, to submit the final outcome of the session.
Note
Ensure that the session token is accurately extracted from the redirect URL query string parameters and that valid survey platform authentication credentials are provided for access.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
token | path | string | true | Token used to identify the session. |
Example responses
200 Response
{
"session_id": "43ac6dbbecbf85927db36f02b57c2958",
"survey_platform_id": "DECIPHER",
"survey_id": "123542",
"survey_url": "https://survey-platform.com/survey/e9790abf",
"supplier_id": "LIFEPOINTS",
"custom_panel_data": {
"internal_id": "213"
},
"panelist_id": "562",
"panelist_profile": {
"age": 55,
"sex": "female",
"pets": "1|2|4|7"
}
}
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Detailed information about the session | RetrieveSessionResponse |
400 | Bad Request | Validation error | ValidationError |
401 | Unauthorized | Access token is missing or invalid | Error |
500 | Internal Server Error | Unexpected error | Error |
Code samples
# You can also use wget
curl -X POST https://router.demo.gateway.kantar.com/panelist-outcome \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'x-api-key: API_KEY'
POST https://router.demo.gateway.kantar.com/panelist-outcome HTTP/1.1
Content-Type: application/json
Accept: application/json
const inputBody = '{
"session_id": "43ac6dbbecbf85927db36f02b57c2958",
"outcome": "COMPLETED",
"metadata": {
"timestamp": "2021-01-01T00:00:00Z"
}
}';
const headers = {
'Content-Type':'application/json',
'Accept':'application/json',
'x-api-key':'API_KEY'
};
fetch('https://router.demo.gateway.kantar.com/panelist-outcome',
{
method: 'POST',
body: inputBody,
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
require 'rest-client'
require 'json'
headers = {
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'x-api-key' => 'API_KEY'
}
result = RestClient.POST 'https://router.demo.gateway.kantar.com/panelist-outcome',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'x-api-key': 'API_KEY'
}
r = requests.POST('https://router.demo.gateway.kantar.com/panelist-outcome', headers = headers)
print(r.json())
<?php
require 'vendor/autoload.php';
$headers = array(
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'x-api-key' => 'API_KEY',
);
$client = new \GuzzleHttp\Client();
// Define array of request body.
$request_body = array();
try {
$response = $client->request('POST','https://router.demo.gateway.kantar.com/panelist-outcome', array(
'headers' => $headers,
'json' => $request_body,
)
);
print_r($response->getBody()->getContents());
}
catch (\GuzzleHttp\Exception\BadResponseException $e) {
// handle exception or api errors.
print_r($e->getMessage());
}
// ...
URL obj = new URL("https://router.demo.gateway.kantar.com/panelist-outcome");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
package main
import (
"bytes"
"net/http"
)
func main() {
headers := map[string][]string{
"Content-Type": []string{"application/json"},
"Accept": []string{"application/json"},
"x-api-key": []string{"API_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := http.NewRequest("POST", "https://router.demo.gateway.kantar.com/panelist-outcome", data)
req.Header = headers
client := &http.Client{}
resp, err := client.Do(req)
// ...
}
POST Panelist Outcome
POST /panelist-outcome
To be used by Survey Platforms
The Panelist Outcome Endpoint allows survey platforms to submit the final outcome of a survey session for a panelist.
By providing the session ID obtained from the session creation process, along with survey outcome details and authentication credentials, survey platforms can update the session status and receive the final redirect URL.
This URL is used to redirect the panelist back to the supplier after completing the survey, facilitating a smooth user experience.
Usage Guidelines
- Obtain Session ID: Retrieve the session ID obtained at the start of the session, from the retrieve session endpoint.
- Post Survey Outcome: Send a POST request to the panelist outcomes endpoint, including the session ID, survey outcome details payload according to the schema, and valid survey platform authentication credentials.
- Receive Final Redirect URL: Upon successful submission, the endpoint updates the session status and returns the final redirect URL for the panelist, enabling seamless redirection back to the supplier.
- Redirect the panelist back: Redirect the panelist back securely using the provided URL.
Note
Ensure that the session ID and survey outcome details are accurately provided in the request payload, and valid survey platform authentication credentials are included for access.
A malformed request or missing authentication credentials will result in an error response from the endpoint.
Body parameter
{
"session_id": "43ac6dbbecbf85927db36f02b57c2958",
"outcome": "COMPLETED",
"metadata": {
"timestamp": "2021-01-01T00:00:00Z"
}
}
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
body | body | PanelistSurveyOutcome | true | Request body containing the outcome of the survey |
Example responses
200 Response
{
"redirect_url": "https://session.kantar.com/sessions/finish/43ac6dbbecbf85927db36f02b57c2958"
}
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Redirect URL for the panelist | PanelistSurveyOutcomeResponse |
400 | Bad Request | Validation error | ValidationError |
401 | Unauthorized | Access token is missing or invalid | Error |
500 | Internal Server Error | Unexpected error | Error |
Schemas
SurveyPlan
{
"survey_id": "demand-survey-plan-id",
"categories": [
"pets",
"wildlife conservation"
],
"country": "USA",
"locale": "es-US",
"survey_url": "https://survey-platform.com/survey/e9790abf",
"type": "interview",
"tags": [
"collects_pii",
"webcam"
],
"estimated_loi": 5,
"estimated_cr": 25,
"estimated_ir": 80,
"target_completes": 30,
"survey_platform": "Decipher",
"target_panels": [
{
"name": "lifepoints"
}
],
"pricing": {
"cpi": 150,
"unit": "fractional",
"currency": "USD"
},
"additional_qualification_count": 3,
"quotas": [
{
"id": "demand-partner-quota-id",
"qualifications": [
{
"question_id": "age",
"qualifying_answers": [
{
"start": 16,
"end": 21
}
]
}
],
"additional_qualification_count": 3,
"pricing": {
"cpi": 150,
"unit": "fractional",
"currency": "USD"
},
"target_completes": 30
}
],
"qualifications": [
{
"question_id": "age",
"qualifying_answers": [
{
"start": 16,
"end": 21
}
]
}
],
"resume_allowed": false,
"group_id": "group-id",
"project_id": "project-id",
"contact_emails": [
"email_one@email.com",
"email_two@email.com",
"email_three@email.com"
],
"finish_date": "2024-09-23T00:00:00.000Z",
"device_requirements": [
"desktop",
"mobile"
]
}
Properties
Name | Type | Required | Description |
---|---|---|---|
survey_id | string | true | ID configured by the demand partner for the survey plan |
categories | [string] | false | What’s the survey plan about |
country | string | true | Country survey plan is targeting, using ISO 3166-1 alpha-3 codes |
locale | string | false | Locale for the survey in langcode_COUNTRYCODE format, where langcode is an ISO 639-1 code (lowercase) and COUNTRYCODE is an ISO 3166-1 alpha-2 code (uppercase), e.g., es-US for Spanish in the USA |
survey_url | string(uri) | true | URL where the final survey is hosted. Using template placeholders you may be able to include certain information dynamically by putting the name of the variable between double parenthesis, for example: ((var_id)). Currently, most information is included via the session token, from the survey plan metadata itself. |
type | string | true | Type of survey. See possible values below. |
tags | [string] | false | Other information about the survey |
estimated_loi | integer | true | Length of interview |
estimated_cr | integer | true | Conversion rate |
estimated_ir | integer | true | Incidence rate |
target_completes | integer | true | Number of completes needed for this survey |
survey_platform | string | true | Targeted survey platform. For non-integrated survey platforms, use ‘NON_INTEGRATED_SURVEY_PLATFORM’ |
target_panels | [Panel] | true | Targeted panels for the survey |
pricing | Pricing | true | Pricing information for the survey |
additional_qualification_count | integer | false | Number of additional qualifications that are not listed in the qualifications array |
quotas | [Quota] | true | Quotas for the survey |
qualifications | [Qualification] | true | Targeting qualifications for the survey |
resume_allowed | boolean | false | Specify if users are allowed to resume the survey or not |
group_id | string | false | The group ID of the survey |
project_id | string | false | The project ID of the survey |
contact_emails | [string] | false | Emails of the project owners |
finish_date | string(date-time) | false | The projected end date and time of the survey in ISO 8601 format |
device_requirements | [string] | false | List of allowed device types |
Enumerated Values
Property | Value |
---|---|
type | interview |
type | tracker |
CreateSurveyPlanResponse
{
"id": "ppg-survey-plan-id"
}
Properties
Name | Type | Required | Description |
---|---|---|---|
id | string | true | ID used to identify the survey plan |
GetSurveyPlanResponse
{
"survey_plan": {
"id": "ppg-survey-plan-id",
"categories": [
"pets",
"wildlife conservation"
],
"country": "USA",
"locale": "es-US",
"survey_url": "https://survey-platform.com/survey/e9790abf",
"type": "interview",
"tags": [
"collects_pii",
"webcam"
],
"estimated_loi": 5,
"estimated_cr": 25,
"estimated_ir": 80,
"target_completes": 30,
"survey_platform": "Decipher",
"status": "OPEN",
"target_panels": [
{
"name": "lifepoints"
}
],
"pricing": {
"cpi": 150,
"unit": "fractional",
"currency": "USD"
},
"additional_qualification_count": 3,
"quotas": [
{
"id": "demand-partner-quota-id",
"qualifications": [
{
"question_id": "age",
"qualifying_answers": [
{
"start": 16,
"end": 21
}
]
}
],
"additional_qualification_count": 3,
"pricing": {
"cpi": 150,
"unit": "fractional",
"currency": "USD"
},
"target_completes": 30,
"status": "OPEN"
}
],
"qualifications": [
{
"question_id": "age",
"qualifying_answers": [
{
"start": 16,
"end": 21
}
]
}
],
"resume_allowed": false,
"group_id": "group-id",
"project_id": "project-id",
"contact_emails": [
"email_one@email.com",
"email_two@email.com",
"email_three@email.com"
],
"finish_date": "2024-09-23T00:00:00.000Z",
"device_requirements": [
"desktop",
"mobile"
]
},
"available_completes": {
"survey": 30,
"quotas": {
"quotaId1": 50,
"quotaId2": 60
}
},
"survey_performance": {
"completes": 2,
"failures": 8,
"status_metrics": {
"property1": {
"COMPLETED": 2,
"TERMINATED": 5,
"REJECTED": 2,
"DISQUALIFIED": 1
},
"property2": {
"COMPLETED": 2,
"TERMINATED": 5,
"REJECTED": 2,
"DISQUALIFIED": 1
}
}
}
}
Properties
Name | Type | Required | Description |
---|---|---|---|
survey_plan | SurveyPlanWithStatus | true | Survey plan details |
available_completes | AvailableCompletes | true | Available completes for survey and quotas |
survey_performance | SurveyPerformance | false | Performance metrics of the survey |
QuotaWithStatus
{
"id": "demand-partner-quota-id",
"qualifications": [
{
"question_id": "age",
"qualifying_answers": [
{
"start": 16,
"end": 21
}
]
}
],
"additional_qualification_count": 3,
"pricing": {
"cpi": 150,
"unit": "fractional",
"currency": "USD"
},
"target_completes": 30,
"status": "OPEN"
}
Properties
Name | Type | Required | Description |
---|---|---|---|
id | string | true | none |
qualifications | [Qualification] | true | none |
additional_qualification_count | integer | false | none |
pricing | Pricing | false | Pricing information for the individual quota |
target_completes | integer | false | Number of completes needed for this survey quota |
status | Status | false | status of the quota |
SurveyPlanWithStatus
{
"id": "ppg-survey-plan-id",
"categories": [
"pets",
"wildlife conservation"
],
"country": "USA",
"locale": "es-US",
"survey_url": "https://survey-platform.com/survey/e9790abf",
"type": "interview",
"tags": [
"collects_pii",
"webcam"
],
"estimated_loi": 5,
"estimated_cr": 25,
"estimated_ir": 80,
"target_completes": 30,
"survey_platform": "Decipher",
"status": "OPEN",
"target_panels": [
{
"name": "lifepoints"
}
],
"pricing": {
"cpi": 150,
"unit": "fractional",
"currency": "USD"
},
"additional_qualification_count": 3,
"quotas": [
{
"id": "demand-partner-quota-id",
"qualifications": [
{
"question_id": "age",
"qualifying_answers": [
{
"start": 16,
"end": 21
}
]
}
],
"additional_qualification_count": 3,
"pricing": {
"cpi": 150,
"unit": "fractional",
"currency": "USD"
},
"target_completes": 30,
"status": "OPEN"
}
],
"qualifications": [
{
"question_id": "age",
"qualifying_answers": [
{
"start": 16,
"end": 21
}
]
}
],
"resume_allowed": false,
"group_id": "group-id",
"project_id": "project-id",
"contact_emails": [
"email_one@email.com",
"email_two@email.com",
"email_three@email.com"
],
"finish_date": "2024-09-23T00:00:00.000Z",
"device_requirements": [
"desktop",
"mobile"
]
}
Properties
Name | Type | Required | Description |
---|---|---|---|
id | string | true | The ID of the survey plan that responded upon its creation |
categories | [string] | false | What’s the survey plan about |
country | string | true | Country survey plan is targeting, using ISO 3166-1 alpha-3 codes |
locale | string | false | Locale for the survey in langcode_COUNTRYCODE format, where langcode is an ISO 639-1 code (lowercase) and COUNTRYCODE is an ISO 3166-1 alpha-2 code (uppercase), e.g., es-US for Spanish in the USA |
survey_url | string(uri) | true | URL where the final survey is hosted. Using template placeholders you may be able to include certain information dynamically by putting the name of the variable between double curly braces, for example: . Currently, most information is included via the session token, from the survey plan metadata itself. |
type | string | true | Type of survey. See possible values below. |
tags | [string] | false | Other information about the survey |
estimated_loi | integer | true | Length of interview |
estimated_cr | integer | true | Conversion rate |
estimated_ir | integer | true | Incidence rate |
target_completes | integer | true | Number of completes needed for this survey |
survey_platform | string | true | Targeted survey platform |
status | Status | true | status of the quota |
target_panels | [Panel] | true | Targeted panels for the survey |
pricing | Pricing | true | Pricing information for the survey |
additional_qualification_count | integer | false | Number of additional qualifications that are not listed in the qualifications array |
quotas | [QuotaWithStatus] | true | Quotas for the survey |
qualifications | [Qualification] | true | Targeting qualifications for the survey |
resume_allowed | boolean | false | Specify if users are allowed to resume the survey or not |
group_id | string | false | The group ID of the survey |
project_id | string | false | The project ID of the survey |
contact_emails | [string] | false | Emails of the project owners |
finish_date | string(date-time) | false | The projected end date and time of the survey in ISO 8601 format |
device_requirements | [string] | false | List of allowed device types |
Enumerated Values
Property | Value |
---|---|
type | interview |
type | tracker |
AvailableCompletes
{
"survey": 30,
"quotas": {
"quotaId1": 50,
"quotaId2": 60
}
}
Properties
Name | Type | Required | Description |
---|---|---|---|
survey | number | true | Available completes for Survey. |
quotas | object | true | Available completes for Quotas |
» additionalProperties | number | false | none |
SurveyPlanUpdate
{
"version": "3052896:1711272468123",
"ack_id": 1711272468123,
"survey_session_creation_url": "https://gateway.kantar.com/panels/123456/session/34829348329d893",
"survey_plan": {
"id": "panel-survey-plan-id",
"categories": [
"pets",
"wildlife conservation"
],
"country": "USA",
"locale": "es-US",
"type": "interview",
"tags": [
"collects_pii",
"webcam"
],
"loi": 5,
"cr": 25,
"ir": 80,
"available_completes": 30,
"pricing": {
"cpi": 150,
"unit": "fractional",
"currency": "USD"
},
"additional_qualification_count": 3,
"status": "OPEN",
"quotas": [
{
"id": "demand-partner-quota-id",
"available_completes": 5,
"status": "OPEN",
"qualifications": [
{
"question_id": "age",
"qualifying_answers": [
"16-40"
]
}
],
"additional_qualification_count": 3,
"pricing": {
"cpi": 150,
"unit": "fractional",
"currency": "USD"
}
}
],
"qualifications": [
{
"question_id": "age",
"qualifying_answers": [
"16-40"
]
}
],
"resume_allowed": false,
"group_id": "group-id",
"project_id": "project-id",
"contact_emails": [
"email_one@email.com",
"email_two@email.com",
"email_three@email.com"
],
"finish_date": "2024-09-23T00:00:00.000Z",
"device_requirements": [
"desktop",
"mobile"
]
}
}
Properties
Name | Type | Required | Description |
---|---|---|---|
version | string | true | Version of the survey plan |
ack_id | number | true | ID used to ack this version of the survey plan |
survey_session_creation_url | string | false | Session URL to submit panelist information and obtain survey entry URL |
survey_plan | SupplierSurveyPlan | true | Survey plan details |
Panel
{
"name": "lifepoints"
}
Properties
Name | Type | Required | Description |
---|---|---|---|
name | string | true | Targeted panel name |
EditSurveyPlanRequest
{
"status": "OPEN"
}
Properties
Name | Type | Required | Description |
---|---|---|---|
status | Status | false | The status of the survey or quota |
EditSurveyPlanResponse
{
"id": "ppg-survey-plan-id",
"message": "string"
}
Properties
Name | Type | Required | Description |
---|---|---|---|
id | string | true | Unique identifier for the survey plan. |
message | string | true | Confirmation message indicating successful receipt of your update request. |
EditQuotaRequest
{
"status": "OPEN"
}
Properties
Name | Type | Required | Description |
---|---|---|---|
status | Status | false | The status of the survey or quota |
EditQuotaResponse
{
"id": "ppg-survey-plan-id",
"survey_plan_status": "OPEN",
"message": "string"
}
Properties
Name | Type | Required | Description |
---|---|---|---|
id | string | true | Unique identifier for the survey plan. |
survey_plan_status | Status | false | The status of the survey or quota |
message | string | false | Confirmation message indicating successful receipt of your update request. |
SupplierSurveyPlan
{
"id": "panel-survey-plan-id",
"categories": [
"pets",
"wildlife conservation"
],
"country": "USA",
"locale": "es-US",
"type": "interview",
"tags": [
"collects_pii",
"webcam"
],
"loi": 5,
"cr": 25,
"ir": 80,
"available_completes": 30,
"pricing": {
"cpi": 150,
"unit": "fractional",
"currency": "USD"
},
"additional_qualification_count": 3,
"status": "OPEN",
"quotas": [
{
"id": "demand-partner-quota-id",
"available_completes": 5,
"status": "OPEN",
"qualifications": [
{
"question_id": "age",
"qualifying_answers": [
"16-40"
]
}
],
"additional_qualification_count": 3,
"pricing": {
"cpi": 150,
"unit": "fractional",
"currency": "USD"
}
}
],
"qualifications": [
{
"question_id": "age",
"qualifying_answers": [
"16-40"
]
}
],
"resume_allowed": false,
"group_id": "group-id",
"project_id": "project-id",
"contact_emails": [
"email_one@email.com",
"email_two@email.com",
"email_three@email.com"
],
"finish_date": "2024-09-23T00:00:00.000Z",
"device_requirements": [
"desktop",
"mobile"
]
}
Properties
Name | Type | Required | Description |
---|---|---|---|
id | string | true | ID used to identify the survey plan |
categories | [string] | false | What’s the survey plan about |
country | string | true | Country survey plan is targeting, using ISO 3166-1 alpha-3 codes |
locale | string | false | Locale for the survey in langcode_COUNTRYCODE format, where langcode is an ISO 639-1 code (lowercase) and COUNTRYCODE is an ISO 3166-1 alpha-2 code (uppercase), e.g., es-US for Spanish in the USA |
type | string | true | Type of survey. See possible values below. |
tags | [string] | false | Other information about the survey |
loi | integer | true | Length of interview |
cr | integer | true | Conversion rate |
ir | integer | true | Incidence rate |
available_completes | integer | true | Number of completes available for this survey |
pricing | Pricing | true | Pricing information for the survey |
additional_qualification_count | integer | false | Number of additional qualifications that are not listed in the qualifications array |
status | Status | true | The status of the survey |
quotas | [object] | true | Quotas for the survey |
» id | string | true | none |
» available_completes | integer | true | Number of completes available for this quota |
» status | Status | true | The status of the quota |
» qualifications | [SupplierSurveyPlan/properties/qualifications/items] | true | none |
» additional_qualification_count | integer | false | none |
» pricing | Pricing | false | Pricing information for the individual quota |
qualifications | [object] | true | Targeting qualifications for the survey |
» question_id | Question | true | The question Id |
» qualifying_answers | [string] | true | Either a single choice or range answer according to the profiling question |
resume_allowed | boolean | false | Specify if users are allowed to resume the survey or not |
group_id | string | false | The group ID of the survey |
project_id | string | false | The project ID of the survey |
contact_emails | [string] | false | Emails of the project owners |
finish_date | string(date-time) | false | The projected end date and time of the survey in ISO 8601 format |
device_requirements | [string] | false | List of allowed device types |
Enumerated Values
Property | Value |
---|---|
type | interview |
type | tracker |
Status
"OPEN"
The status of the survey or quota
Properties
Name | Type | Required | Description |
---|---|---|---|
- | string | false | The status of the survey or quota |
Enumerated Values
Property | Value |
---|---|
- | OPEN |
- | CLOSED |
- | PAUSED |
SurveyPlanUpdatesResponse
[
{
"version": "3052896:1711272468123",
"ack_id": 1711272468123,
"survey_session_creation_url": "https://gateway.kantar.com/panels/123456/session/34829348329d893",
"survey_plan": {
"id": "panel-survey-plan-id",
"categories": [
"pets",
"wildlife conservation"
],
"country": "USA",
"locale": "es-US",
"type": "interview",
"tags": [
"collects_pii",
"webcam"
],
"loi": 5,
"cr": 25,
"ir": 80,
"available_completes": 30,
"pricing": {
"cpi": 150,
"unit": "fractional",
"currency": "USD"
},
"additional_qualification_count": 3,
"status": "OPEN",
"quotas": [
{
"id": "demand-partner-quota-id",
"available_completes": 5,
"status": "OPEN",
"qualifications": [
{
"question_id": "age",
"qualifying_answers": [
"16-40"
]
}
],
"additional_qualification_count": 3,
"pricing": {
"cpi": 150,
"unit": "fractional",
"currency": "USD"
}
}
],
"qualifications": [
{
"question_id": "age",
"qualifying_answers": [
"16-40"
]
}
],
"resume_allowed": false,
"group_id": "group-id",
"project_id": "project-id",
"contact_emails": [
"email_one@email.com",
"email_two@email.com",
"email_three@email.com"
],
"finish_date": "2024-09-23T00:00:00.000Z",
"device_requirements": [
"desktop",
"mobile"
]
}
}
]
Properties
Name | Type | Required | Description |
---|---|---|---|
- | [SurveyPlanUpdate] | false | none |
SurveyPlanUpdateAck
{
"ack_id": 1711272468123
}
Request body to ack a survey plan.
Properties
Name | Type | Required | Description |
---|---|---|---|
ack_id | number | true | ID of the latest survey plan update processed |
SurveySession
{
"panelist_id": "123456",
"target_quota_id": "1",
"custom_panel_data": {
"internal_id": "213"
},
"panelist_profile": {
"age": 22,
"sex": "male",
"pets": "1|2|4|7"
}
}
Request body to create a survey session.
Properties
Name | Type | Required | Description |
---|---|---|---|
panelist_id | string | true | The ID for the panelist is the panel platform |
target_quota_id | string | false | The ID for the target quota |
custom_panel_data | object | false | Custom panel data |
panelist_profile | object | false | JSON object containing the Panelist profile information, using standard targeting attributes |
CreateSurveySessionResponse
{
"url": "https://session.kantar.com/sessions/start/43ac6dbbecbf85927db36f02b57c2958"
}
Properties
Name | Type | Required | Description |
---|---|---|---|
url | string | true | The entry link used to start the survey session. Suppliers will redirect panelists to this URL. |
RetrieveSessionResponse
{
"session_id": "43ac6dbbecbf85927db36f02b57c2958",
"survey_platform_id": "DECIPHER",
"survey_id": "123542",
"survey_url": "https://survey-platform.com/survey/e9790abf",
"supplier_id": "LIFEPOINTS",
"custom_panel_data": {
"internal_id": "213"
},
"panelist_id": "562",
"panelist_profile": {
"age": 55,
"sex": "female",
"pets": "1|2|4|7"
}
}
Properties
Name | Type | Required | Description |
---|---|---|---|
session_id | string | true | ID for the session |
survey_platform_id | string | true | ID of the survey platform |
survey_id | string | true | ID of the survey |
survey_url | string | false | The URL of where the survey is hosted |
supplier_id | string | true | ID of the supplier |
custom_panel_data | object | false | Custom metadata sent by the panel |
panelist_id | string | true | The ID of the panelist |
panelist_profile | object | false | JSON object containing the Panelist profile information, using standard targeting attributes |
PanelistSurveyOutcome
{
"session_id": "43ac6dbbecbf85927db36f02b57c2958",
"outcome": "COMPLETED",
"metadata": {
"timestamp": "2021-01-01T00:00:00Z"
}
}
Survey Outcome Statuses
This is the request body containing the outcome of the survey. Survey outcome statuses represent the various states that a survey session can have after being completion. These statuses provide valuable insights into the success or failure of a survey session and help in understanding panelist interactions.
List of Outcome Statuses:
- COMPLETED: Indicates that the survey was successfully completed by the panelist.
- TERMINATED: Indicates that the survey session was terminated prematurely, often by the panelist.
- DISQUALIFIED: Indicates that the panelist was disqualified from completing the survey.
- SCREENED_OUT: Indicates that the panelist was screened out and not eligible to complete the survey.
- REJECTED: Indicates that the survey response was rejected due to invalid or incomplete data.
- QUOTA_FULL: Indicates that the survey quota for a particular group or segment has been reached.
- ERROR: Indicates that an error occurred during the survey process, preventing completion.
- TIMEOUT: Indicates that the survey session timed out due to inactivity, and the survey could not be completed.
Properties
Name | Type | Required | Description |
---|---|---|---|
session_id | string | true | The sessionID of the survey |
outcome | string | true | The outcome of the survey. See the list of possible outcomes below. |
metadata | object | false | Metadata of the survey |
Enumerated Values
Property | Value |
---|---|
outcome | COMPLETED |
outcome | TERMINATED |
outcome | DISQUALIFIED |
outcome | SCREENED_OUT |
outcome | REJECTED |
outcome | QUOTA_FULL |
outcome | ERROR |
outcome | TIMEOUT |
PanelistSurveyOutcomeResponse
{
"redirect_url": "https://session.kantar.com/sessions/finish/43ac6dbbecbf85927db36f02b57c2958"
}
Properties
Name | Type | Required | Description |
---|---|---|---|
redirect_url | string | true | The final URL used to route the panelist back to the supplier |
Pricing
{
"cpi": 150,
"unit": "fractional",
"currency": "USD"
}
Properties
Name | Type | Required | Description |
---|---|---|---|
cpi | integer | true | Cost per interview |
unit | string | true | The “main” unit represents the primary currency unit (e.g., dollars, pounds), while the “fractional” unit represents the subunit of the currency (e.g., cents, pence). Values in the cpi field should be integers, with fractional amounts converted to their equivalent subunits. |
currency | string | true | Currency code in ISO 4217 format |
Enumerated Values
Property | Value |
---|---|
unit | fractional |
unit | main |
currency | USD |
currency | GBP |
currency | AUD |
currency | CAD |
currency | EUR |
Quota
{
"id": "demand-partner-quota-id",
"qualifications": [
{
"question_id": "age",
"qualifying_answers": [
{
"start": 16,
"end": 21
}
]
}
],
"additional_qualification_count": 3,
"pricing": {
"cpi": 150,
"unit": "fractional",
"currency": "USD"
},
"target_completes": 30
}
Properties
Name | Type | Required | Description |
---|---|---|---|
id | string | true | none |
qualifications | [Qualification] | true | none |
additional_qualification_count | integer | false | none |
pricing | Pricing | false | Pricing information for the individual quota |
target_completes | integer | false | Number of completes needed for this survey quota |
Qualification
{
"question_id": "age",
"qualifying_answers": [
{
"start": 16,
"end": 21
}
]
}
Properties
Name | Type | Required | Description |
---|---|---|---|
question_id | Question | true | The question Id |
qualifying_answers | any | true | Either a single choice or range answer according to the profiling question |
oneOf
Name | Type | Required | Description |
---|---|---|---|
» - | [string] | false | none |
xor
Name | Type | Required | Description |
---|---|---|---|
» - | [RangeAnswer] | false | none |
TargetingAttribute
[
{
"id": "sex",
"text": "What do you most closely identify as?",
"answer_type": "single_choice",
"supported_countries": [
"USA",
"GBR"
],
"answers": [
{
"id": "male",
"text": "Male"
},
{
"id": "female",
"text": "Female"
}
]
},
{
"id": "pets",
"text": "What pets/animals do you keep?",
"answers_type": "multi_punch",
"supported_countries": [
"USA"
],
"answers": [
{
"id": "2",
"text": "Dog(s)",
"exclusive_multi_punch_answer": false
},
{
"id": "10",
"text": "Fish",
"exclusive_multi_punch_answer": false
},
{
"id": "7",
"text": "Bird(s)",
"exclusive_multi_punch_answer": false
},
{
"id": "9",
"text": "Horse(s)",
"exclusive_multi_punch_answer": false
},
{
"id": "5",
"text": "I don't have pets",
"exclusive_multi_punch_answer": true
},
{
"id": "none",
"text": "n/a",
"exclusive_multi_punch_answer": false
},
{
"id": "1",
"text": "Cat(s)",
"exclusive_multi_punch_answer": false
},
{
"id": "8",
"text": "Reptile(s)",
"exclusive_multi_punch_answer": false
},
{
"id": "4",
"text": "Other(s)",
"exclusive_multi_punch_answer": false
},
{
"id": "11",
"text": "Prefer not to say",
"exclusive_multi_punch_answer": true
}
]
}
]
Properties
Name | Type | Required | Description |
---|---|---|---|
id | Question | true | Question identifier |
text | string | true | The question that is being asked |
answer_type | string | true | Either a single choice, range question or multi punch depending on the targeting question |
supported_countries | [string] | false | Profiling question for specific country |
range_limits or answers | any | false | Either a single choice or range answer depending on the targeting question |
oneOf
Name | Type | Required | Description |
---|---|---|---|
» - | [SingleChoiceAnswer] | false | none |
xor
Name | Type | Required | Description |
---|---|---|---|
» - | RangeAnswer | false | none |
xor
Name | Type | Required | Description |
---|---|---|---|
» - | MultiPunchAnswer | false | none |
Enumerated Values
Property | Value |
---|---|
answer_type | single_choice |
answer_type | range |
answer_type | multi_punch |
TargetingAttributeResponse
{
"targeting_attributes": [
{
"id": "age",
"text": "What is your age?",
"answers_type": "range",
"range_limits": {
"start": 16,
"end": 100
}
},
{
"id": "sex",
"text": "What do you most closely identify as?",
"answer_type": "single_choice",
"supported_countries": [
"USA",
"GBR"
],
"answers": [
{
"id": "male",
"text": "Male"
},
{
"id": "female",
"text": "Female"
}
]
}
]
}
Properties
Name | Type | Required | Description |
---|---|---|---|
targetingAttributes | [TargetingAttribute] | false | An array of targeting attribute question objects |
TargetingPanelsResponse
{
"panel1": {
"GBR": {
"locales": [
"en-GB"
],
"currency": "GBP"
},
"USA": {
"locales": [
"en-US",
"es-US"
],
"currency": "USD"
}
},
"panel2": {
"ITA": {
"locales": [
"it-IT"
],
"currency": "EUR"
},
"USA": {
"locales": [
"en-US",
"es-US"
],
"currency": "USD"
}
},
"panel3": {
"CAN": {
"locales": [
"fr-CA",
"en-CA"
],
"currency": "CAD"
},
"CHE": {
"locales": [
"de-CH",
"fr-CH",
"it-CH"
],
"currency": "CHF"
}
}
}
An object containing configurations for various targeting panels.
Properties
Name | Type | Required | Description |
---|---|---|---|
additionalProperties | any | false | none |
RangeAnswer
{
"start": 16,
"end": 70
}
Properties
Name | Type | Required | Description |
---|---|---|---|
start | integer | true | none |
end | integer | true | none |
Question
"age"
The id of the question
Properties
Name | Type | Required | Description |
---|---|---|---|
- | string | false | The id of the question |
SingleChoiceAnswer
{
"id": "1",
"text": "Higher & intermediate managerial, administrative, professional occupations"
}
Properties
Name | Type | Required | Description |
---|---|---|---|
id | string | true | The id of the answer |
text | string | true | Description of the answer |
MultiPunchAnswer
[
{
"id": "2",
"text": "Dog(s)",
"exclusive_multi_punch_answer": false
},
{
"id": "10",
"text": "Fish",
"exclusive_multi_punch_answer": false
},
{
"id": "7",
"text": "Bird(s)",
"exclusive_multi_punch_answer": false
},
{
"id": "9",
"text": "Horse(s)",
"exclusive_multi_punch_answer": false
},
{
"id": "5",
"text": "I don't have pets",
"exclusive_multi_punch_answer": true
},
{
"id": "none",
"text": "n/a",
"exclusive_multi_punch_answer": false
},
{
"id": "1",
"text": "Cat(s)",
"exclusive_multi_punch_answer": false
},
{
"id": "8",
"text": "Reptile(s)",
"exclusive_multi_punch_answer": false
},
{
"id": "4",
"text": "Other(s)",
"exclusive_multi_punch_answer": false
},
{
"id": "11",
"text": "Prefer not to say",
"exclusive_multi_punch_answer": true
}
]
Properties
Name | Type | Required | Description |
---|---|---|---|
id | string | true | The id of the answer |
text | string | true | Description of the answer |
exclusive_multi_punch_answer | boolean | false | Whether the answer can be selected exclusively or in combination with other answers |
Error
{
"code": "string",
"message": "string",
"success": true
}
Properties
Name | Type | Required | Description |
---|---|---|---|
code | string(int32) | true | none |
message | string | true | none |
success | boolean | false | none |
ValidationError
{
"code": "string",
"message": "string",
"details": [
{
"constraint": "string",
"field": "string",
"message": "string"
}
]
}
Properties
Name | Type | Required | Description |
---|---|---|---|
code | string(int32) | true | none |
message | string | true | none |
details | [ValidationErrorDetail] | true | none |
ValidationErrorDetail
{
"constraint": "string",
"field": "string",
"message": "string"
}
Properties
Name | Type | Required | Description |
---|---|---|---|
constraint | string | true | none |
field | string | true | none |
message | string | true | none |
SurveyPerformance
{
"completes": 2,
"failures": 8,
"status_metrics": {
"property1": {
"COMPLETED": 2,
"TERMINATED": 5,
"REJECTED": 2,
"DISQUALIFIED": 1
},
"property2": {
"COMPLETED": 2,
"TERMINATED": 5,
"REJECTED": 2,
"DISQUALIFIED": 1
}
}
}
Properties
Name | Type | Required | Description |
---|---|---|---|
completes | number | true | Number of successful completions of a survey. |
failures | number | true | Number of failed completions of a survey. |
status_metrics | object | true | Outcome Status of the Survey per panel |
» additionalProperties | StatusMetrics | false | Example of the outcome |
StatusMetrics
{
"COMPLETED": 2,
"TERMINATED": 5,
"REJECTED": 2,
"DISQUALIFIED": 1
}
Properties
Name | Type | Required | Description |
---|---|---|---|
COMPLETED | number | false | Number of completions. |
TERMINATED | number | false | Number of terminations. |
REJECTED | number | false | Number of rejections. |
DISQUALIFIED | number | false | Number of disqualifications. |
Knowledge Base
Router Flow Explanation
The router service is used to manage the flow of survey sessions between the supply and survey platforms, handling tasks such as session creation and routing session information and survey outcomes. The router ensures the integrity of data and establishes a secure pathway for panellists taking a survey.
Survey session start
Supplier
- To begin the flow the supply partner polls the supply API to receive updated or new survey plans. Within each survey plan, an entry link exists which is used by the panel to initiate submit the panelist information and receive the entry link to a survey session.
-
Upon receiving a survey session creation request along with the panelist demographics, the session router initiates authentication and panelist data validation. If successful, it promptly responds with a redirection URL, enabling the panel to send the panelist to stat the survey on the designated survey platform. However, if validation fails, the API will return an error.
-
The supplier will now use the received URL to send the panelist to the start of a survey session.
Survey Platform
- Once successfully redirected into the survey platform, the session information can retrieved from the sessions endpoint . This endpoint will provide additional survey and panelist details, including sessionId, surveyId, and panelist demographics.
Survey Session Finish
Survey Platform
- After completing the survey, the survey platform sends a request to the router’s panelist outcome endpoint, containing the survey outcome. Subsequently, the router responds back by providing a secure redirection URL, enabling the survey platform to return the panelist to the supplier.
Supplier
- The supplier will receive the user into their pre-configured redirect URLs, along with a JWS token with the outcome information. Additionally they will also receive a survey-to-survey postback with this information.
Launch a survey with a non integrated survey platform
1. Configuring your survey entry
To configure the survey with the Kantar Gateway, we will use custom variables to pass information, enabling us to track the survey session.
The Kantar Gateway will provide you with a custom session ID that you will need to send back at the end of the session. This custom ID can be created as a custom variable, if your survey platform supports that.
To configure this custom ID in your survey platform, you have 2 options:
-
You can use our provided placeholder ((SESSION_ID)) in your URL, so we can replace it on entry, i.e. Assuming you have a custom variable (e.g session_var), you can configure your URL like so:
https://www.surveyplatform.com/survey?session_var=((SESSION_ID))
and we’ll replace it on entry. -
If you don’t configure a custom variable of your own, we’ll add a variable named t to your URL on entry with the value of the session, i.e. your original survey URL
https://www.surveyplatform.com/survey
becomeshttps://www.surveyplatform.com/survey?t=((SESSION_ID))
Pass survey and panelist IDs using placeholders like ((SURVEY_ID)) and ((PANELIST_ID)) in your URL. Additional custom variables can also be included as needed. These are not mandatory.
Example shows p as the custom variable for ((PANELIST_ID)) and s as the custom variable for ((SURVEY_ID)):
i.e. https://www.surveyplatform.com/survey?session_var=((SESSION_ID))&s=((SURVEY_ID))&p=((PANELIST_ID))&custom=custom_data
2. Configuring your survey redirect back to us
When redirecting back to us, we’ll need to know 2 values:
The outcome of the session. The original session ID we sent to you on entry.
We provide a specific format you can configure your redirect URLs to pass this information back to us:
https://router.gateway.kantar.com/panelist-outcome/{OUTCOME}?t={SESSION_ID}
Where:
- {OUTCOME} is the placeholder on your platform for the outcome of the survey.
- {SESSION_ID} is the placeholder on your platform for the custom variable we sent you on entry. Notice that we only accept this variable in the query string with the name t.
We provide a testing endpoint that can be configured in the same way:
https://router.demo.gateway.kantar.com/panelist-outcome/{OUTCOME}?t={SESSION_ID}
For instance:
If the panelist completed the survey successfully and we sent you a session ID 12345, you will redirect them to:
https://router.gateway.kantar.com/panelist-outcome/completed?t=12345
If the panelist gets disqualified, redirect them to:
https://router.gateway.kantar.com/panelist-outcome/disqualified?t=12345
For a list of all available outcomes, see the Schemas Section.
3. Launching your survey plan
To launch your survey plan, use the configured survey link and add it to the survey_url
field. Specify that you are using a NON_INTEGRATED_SURVEY_PLATFORM
in the survey_platform
field.