Privacy API: Integrate your Bazaarvoice solution into your privacy regulations compliance workflow using a secure HTTP interface.
Right of Access
The Bazaarvoice Privacy API provides a secure HTTP interface for integrating Bazaarvoice into your privacy regulations compliance workflow. To learn more, go to the Privacy API home page.
Contents
This page describes how to use the accessRequests
resource to process end-user right of access requests.
URL pattern
The following example demonstrates the basic URL pattern for a right of access request. Go to the Tools section to access interactive tools and applications that help you work with the Privacy API.
https://[stg].api.bazaarvoice.com/privacy/accessRequests/{id}?passkey={PRIVACY_API_PASSKEY}
Environments
The following environments are supported:
Environment | Domain | Description |
---|---|---|
Staging |
|
Used while developing your application. |
Production |
|
Used when your application is complete. |
Submitting a right of access request
Create a new accessRequests
resource to request information about an end user. Note that you cannot submit a right of access request for an end user if an existing Right of Access or Right to be Forgotten request for the same end user is still pending.
POST https://[stg.]api.bazaarvoice.com/privacy/v1/accessRequests?passkey={PRIVACY_API_PASSKEY} HTTP/1.1 Content-Type: application/json Authorization: Bearer {ACCESS_TOKEN} … { "emailAddress": "some.email@example.com", "authorId": "12345678", "clientNames": [ "Client-EN_GB", "Client-DE_DE" ] }
Ellipses (…) in above example indicate that your app may generate other headers.
Parameters
Name | Description | Required |
---|---|---|
QueryString |
||
passkey |
Privacy API passkey |
Yes |
Header |
||
Content-Type |
application/json |
Yes |
Authorization |
The Authorization value will consist of the string |
Yes |
Body |
||
emailAddress |
The end-user's email address |
No * |
facebookUsername |
The end-user's Facebook username |
No * |
twitterUsername |
The end-user's Twitter username |
No * |
instagramUsername |
The end-user's Instagram username |
No * |
youtubeChannelId |
The end-user's YouTube channel identifier |
No * |
youtubeUsername |
The end-user's YouTube channel name |
No * |
vimeoUsername |
The end-user's Vimeo username |
No * |
tumblrUsername |
The end-user's Tumblr username |
No * |
flickrUsername |
The end-user's Flickr username |
No * |
pinterestUsername |
The end-user's Pinterest username |
No * |
authorId |
The client-controlled user identifier for Conversations submission. Also known as an "external ID". This identifier must be unique across all clients specified in the request. |
No * |
phoneNumber |
The end-user's phoneNumber. Phone number should start with a '+' sign, followed by digits without any spaces or characters. It cannot contain more than 15 digits.
|
No * |
clientNames |
List of the client names to which the request is scoped. Defaults to the list of clients to which the requester has access. |
No |
* At least one identifier must be included in the POST request.
Response body
Response will be a JSON object. The following demonstrates a typical response in the PENDING
state:
{ "id": "a4bd736d-a9ad-47d2-b145-27978737aac8", "status": "PENDING", "submissionTime": "2018-05-04T18:18:45.009Z", "clientNames": [ "Client-DE_DE", "Client-EN_GB" ], "emailAddress": "some.email@example.com" }
Key/value pairs that are not applicable in all contexts (i.e. ‘completionTime’ for pending requests) are not returned. The downloadUrl
and dataFound
key/value pairs are only present when the status is COMPLETED
. Continue to the next section for information about checking when a request is completed
Retrieving right of access request status
Most Right of Access requests complete within two days of the initial request, although some requests may take several days depending on how data is stored for the end consumer. Once a requests returns a status of COMPLETED
, the data is available for the end consumer. For an accessRequests
resource, check the status in the following ways.
Single request
A request can be scoped to a specific resource by using that resource's ID.
GET https://[stg.]api.bazaarvoice.com/privacy/v1/accessRequests/{id}?passkey={PRIVACY_API_PASSKEY} HTTP/1.1
Authorization: Bearer {ACCESS_TOKEN}
…
Ellipses (…) in above example indicate that your app may generate other headers.
Parameters
Name | Description | Required |
---|---|---|
Path |
||
id |
ID created for a given submission request. |
Yes |
QueryString |
||
passkey |
Privacy API passkey. |
Yes |
Header |
||
Authorization |
The Authorization value will consist of the string |
Yes |
Response body
The following demonstrates a typical response in the PENDING
state:
{ "id": "a4bd736d-a9ad-47d2-b145-27978737aac8", "status": "PENDING", "submissionTime": "2018-05-04T18:18:45.009Z", "clientNames": [ "Client-DE_DE", "Client-EN_GB" ], "emailAddress": "some.email@example.com", "authorId": "12345678" }
The following demonstrates a typical COMPLETED
response:
{ "id": "a4bd736d-a9ad-47d2-b145-27978737aac8", "status": "COMPLETED", "submissionTime": "2018-05-04T18:18:45.009Z", "clientNames": [ "Client-DE_DE", "Client-EN_GB" ], "emailAddress": "some.email@example.com", "dataFound": true, "downloadUrl": "https://example.bazaarvoice.com/download/here", "completionTime":"2018-05-05T10:11:01.006Z" }
Many requests
The following example returns a paginated collection of all available accessRequests
resources available to the user identified by the Authorization header. This supports various query string parameters which are described below.
GET https://[stg.]api.bazaarvoice.com/privacy/v1/accessRequests/?passkey={PRIVACY_API_PASSKEY} HTTP/1.1 Authorization: Bearer {ACCESS_TOKEN} …
Ellipses (…) in above example indicate that your app may generate other headers.
Parameters
Name | Description | Required |
---|---|---|
QueryString |
||
passkey |
Privacy API passkey |
Yes |
Header |
||
Authorization |
The Authorization value will consist of the string |
Yes |
Identifiers
There is the notion of an identifier. These values identify an end-user on various social platforms including Bazaarvoice. Only one identifier can be used in the querystring filter. For instance, ?emailAddress=test@test.com&pinterestUsername=catlover
is not available. The following are the available identifiers:
emailAddress |
instagramUsername |
vimeoUsername |
pinterestUsername |
facebookUsername |
youtubeChannelId |
tumblrUsername |
authorId |
twitterUsername |
youtubeUsername |
flickrUsername |
phoneNumber |
Query string filters
Name | Description |
---|---|
'identifier' |
See discussion above. |
clientName |
Available client instance names |
completedAfter |
Date in ISO format yyyy-mm-ddThh:mm:ss:SSSZ 2018-05-04T18:18:45.009Z |
submittedAfter |
Date in ISO format yyyy-mm-ddThh:mm:ss:SSSZ 2018-05-04T18:18:45.009Z |
status |
Available values: 'PENDING', 'COMPLETED' |
limit |
The maximum number of requests to return. If no limit is specified the default is 100 |
Response body
Response order will be status followed by timestamp. Requests with a PENDING status will be returned first. The secondary sort for pending requests is submissionTime
descending. Requests with a status of COMPLETED will use completionTime
as the secondary sort descending.
Time is in the ISO format yyyy-mm-ddThh:mm:ss:SSSZ (2018-05-04T18:18:45.009Z)
When the response elements exceed the limit querystring parameter, a nextToken
key/value pair is returned that can be used to obtain the subsequent requests. To get the next page, users must specify the nextToken
with the same query parameters. On the final page, the nextToken
will be null. "nextToken": null
The following demonstrates a typical response:
{ "requests": [ { "id": "a4bd736d-a9ad-47d2-b145-27978737aac8", "status": "PENDING", "submissionTime": "2018-05-04T18:18:45.009Z", … }, { "id": "26bac6d9-df55-4685-986b-8c82f36612f9", "status": "PENDING", "submissionTime": "2018-05-04T18:18:45.009Z", … }, { "id": "4c4e2af5-387d-4de3-8704-d78c634ddf94", "status": "COMPLETED", "submissionTime": "2018-05-04T18:18:45.009Z", "completionTime": "2018-05-04T19:17:05.009Z", "dataFound": true, "downloadUrl": "https://example.bazaarvoice.com/download/here", … }, { "id": "65f3a8c8-7c14-4c13-900d-f817fd650657", "status": "COMPLETED", "submissionTime": "2018-05-04T18:18:45.009Z", "completionTime": "2018-05-04T19:17:05.009Z", "dataFound": true, "downloadUrl": "https://example.bazaarvoice.com/download/here", … }, … ], "nextToken": "ISbvurTgnp2HSNAfyhGYn4kKSk7vQrU3g02CB6u6MTNCjuQ=" }
ROA Data Format
On completion of Right of Access request, the response of a status check returns a downloadUrl
field. This secure download link allows you to download a ZIP file that contains the available data associated with the end consumer. The resultant ZIP file can be provided directly to the consumer.
ZIP file contents
When extracted, the ZIP file will contain a directory for each Bazaarvoice client instance that has data on the consumer. For example, if you scoped your request to three client instances, InstanceA, InstanceB, and InstanceC. The first two had data on the consumer, but the last one did not, then you would see two directories when you extract the ZIP file: "InstanceA" and "InstanceB" each representing data stored in the respective client instance.
Directory contents
Each client instance directory structure extracted from the resultant ZIP file will contain two sets of data. One set of JSON files and another set of CSV files representing data associated with the consumer in two of currently supported formats. A consumer can read these JSON files with any text editor. The exact number and name of these JSON files vary from consumer to consumer, depending on how the consumer interacted with Bazaarvoice systems. Furthermore, the fields within each JSON file can vary for the same reasons.
Bazaarvoice does not recommend that you process the JSON files before providing them to the consumer. The ZIP file and its contents are meant for direct consumer consumption. However, if your use case requires you to process the JSON files before providing them to the consumer, your application must handle the JSON files and JSON fields in as general a way as possible rather than hardcode the values you see during testing. In short, you should not expect the JSON files or fields to be the same in name or quantity for each consumer. If you do, your application will encounter errors when the contents differ across requests.
The generated CSV files represent JSON data in a comma-separated manner where each column header represents a respective JSON key, and each record row represents value in a respective JSON object. For example, if the generated JSON file has two JSON objects with four key fields, then the resultant CSV file will contain four columns for the individual key and two rows representing the respective JSON object as in example 1. Further, if it is a complex JSON structure as nested JSON object, the same will be represented with nested-object-name.fieldname as in example 2. For a JSON with nested array, columns are represented with position as depicted in example 3.
The following demonstrates a typical examples.
Example 1 : Simple JSON
JSON File
[ { "clientID" : "client_id 1", "id" : 10159683, "createdDate" : "2018-05-04T18:18:45.009+0000", "amount" : 2312.24 }, { "clientID" : "client_id 2", "id" : 10159683, "createdDate" : "2018-05-04T18:18:45.009+0000", "amount" : 1112.24 } ]
Resultant CSV:
clientID | id | createdDate | amount |
---|---|---|---|
client_id 1 | 10159683 | 2018-05-04T18:18:45.009+0000 | 2312.24 |
client_id 2 | 10159683 | 2018-05-04T18:18:45.009+0000 | 1112.24 |
Example 2: Nested JSON
JSON File
[ { "schemaVersion" : "2018-05-18", "abouId" : 123, "clientName" : "privacy test client", "published" : { "id" : 4994285, "aboutType" : "question" } }, { "schemaVersion" : "2018-05-18", "abouId" : 124, "clientName" : "privacy general client", "published" : { "id" : 4994285, "aboutType" : "question and answer" } } ]
Resultant CSV:
schemaVersion | abouId | clientName | published.id | published.aboutType |
---|---|---|---|---|
2018-05-18 | 123 | privacy test client | 4994285 | question |
2018-05-18 | 124 | privacy general client | 4994285 | question and answer |
Example 3: Arrays
JSON File
[ { "channel" : "instagram", "client" : "privacy test client", "photos" : [ { "origin" : "instagram", "imageUrl" : "httpsn1.jpg" }, { "origin" : "instagram", "imageUrl" : "httpsn2.jpg" } ] } ]
Resultant CSV:
channel | client | photos.0.origin | photos.0.imageUrl | photos.1.origin | photos.1.imageUrl |
---|---|---|---|---|---|
privacy test client | httpsn1.jpg | httpsn2.jpg |
Errors
Please see Troubleshooting for a detailed description and solution for Privacy API errors.