Introduction
API URL
Europe:
https://portal-api.brandactif.com/api/v2/
India:
https://portal-api.brandactif.in/api/v2/
Welcome to the Brandactif API! You can use our API to access Brandactif endpoints.
Authentication
Brandactif uses API keys to allow access to the API. The API key must be included in all API requests to the server in a header that looks like the following:
Api-Key: your-api-key
Scans
Description
It takes 3 steps to perform a scan:
- Get a S3 presigned URL and upload an image
- Create the scan in our database
- Get redirect URL of the scan
The scanning process is asynchronous on our side, so in the second step, you only get the UUID of the created scan, which you then use to fetch its data.
Image restrictions
There are a few rules you have to follow in terms of the image files you want to use:
- supported formats are
jpg
/jpeg
andpng
(without transparency) - file size should be less than 2MB
- dimensions must be higher than 400 x 400 px and lower than 1200 x 1200 px
- proportions of the image must be close to a square (aspect ratio between 0.5 and 2)
- images must be sent with minimum compression quality of 80%
- filename must consist only of following characters:
0-9
a-z
A-Z
!
-
_
.
*
'
(
)
Upload image
Description
Your first step is to get a S3 presigned URL which you can then use to upload your scan image.
Example request
curl --request POST \
--url https://portal-api.brandactif.com/api/v2/presigned_url \
--header 'api-key: d5b3af44cd0f967e9f4218a4131d85ec522cc865a246fa23792a8f3836f21caf' \
--header 'content-type: application/json' \
--data '{
"presigned_url": {
"type": "scan",
"filename": "example.jpg"
}
}'
The above command returns JSON with the following structure:
{
"uuid": "083e5f81-ef66-49a9-a274-b927bdd19464",
"upload_url": "https://s3.us-east-2.amazonaws.com/presigned-url-example/path/to/your/file/083e5f81-ef66-49a9-a274-b927bdd19464/image/example.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...&X-Amz-Date=20181107T093628Z&X-Amz-Expires=600&X-Amz-SignedHeaders=host&X-Amz-Signature=..."
}
HTTP Request
POST https://portal-api.brandactif.com/api/v2/presigned_url
Body parameters
Body
Parameter | Type | Required | Description |
---|---|---|---|
presigned_url |
object | true | object containing presign details below |
Body/presigned_url
Parameter | Type | Required | Description |
---|---|---|---|
type |
string | true | must have a value of scan |
image_filename |
string | true | filename of a scan image |
Response
201 Created
HTTP status and JSON with two keys:
Parameter | Description |
---|---|
uuid |
UUID to identify an image in next steps |
upload_url |
URL to which you can upload your image |
Upload
Uploading an image using a presigned URL can be performed by simply making a PUT request with a file in a request body.
Example (simplified) request
curl --request PUT \
--url 'https://s3.us-east-2.amazonaws.com/presigned-url-example/path/to/your/file/083e5f81-ef66-49a9-a274-b927bdd19464/image/example.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...&X-Amz-Date=20181107T093628Z&X-Amz-Expires=600&X-Amz-SignedHeaders=host&X-Amz-Signature=...' \
--header 'content-type: image/jpeg' \
--data-binary @filepath
Create scan
Description
Once your upload was successfully completed, the next step is to send a POST
request to create a scan in our database.
Example request
curl --request POST \
--url https://portal-api.brandactif.com/api/v2/scans/ \
--header 'api-key: d5b3af44cd0f967e9f4218a4131d85ec522cc865a246fa23792a8f3836f21caf' \
--header 'content-type: application/json' \
--data '{
"scan": {
"image_filename": "example.jpg",
"image_uuid": "083e5f81-ef66-49a9-a274-b927bdd19464",
"latitude": 35.126114,
"longitude": -106.536563,
"metadata": "{\"platform\":\"Android\",\"os_version\":\"8.1\",\"browser\":\"Chrome Mobile\",\"language\":\"en-US\"}"
}
}'
The above command returns JSON with the following structure:
{
"uuid": "083e5f81-ef66-49a9-a274-b927bdd19464"
}
HTTP Request
POST https://portal-api.brandactif.com/api/v2/scans
Body parameters
Body
Parameter | Type | Required | Description |
---|---|---|---|
scan |
object | true | object containing scan details below |
Body/scan
Parameter | Type | Required | Description |
---|---|---|---|
image_filename |
string | true | filename of a scan image |
image_uuid |
string | true | UUID received in previous step |
latitude , longitude |
float | false | coordinates of the device performing a scan |
metadata |
string | false | stringified JSON object with additional parameters of the device performing a scan |
Response
202 Accepted
HTTP status with uuid
of your scan in a request body.
Get scan
Description
After a scan object was created in our database, the matching process was started in the background.
You can now start asking for a redirect URL of the scan. The scanning process usually takes less than a second, but we recommend to set a minimum 1-second delay between creating a scan and fetching its data.
If the scan status is still performing
you should refetch a data repeatedly in time intervals (not less than 500ms) until you receive one of the 3 final statuses (performed
, failed_to_perform
or failed_upload_to_aws
).
Example request
curl --request GET \
--url https://portal-api.brandactif.com/api/v2/scans/083e5f81-ef66-49a9-a274-b927bdd19464 \
--header 'api-key: d5b3af44cd0f967e9f4218a4131d85ec522cc865a246fa23792a8f3836f21caf' \
--header 'content-type: application/json'
The above command returns JSON with the following structure:
{
"uuid": "083e5f81-ef66-49a9-a274-b927bdd19464",
"status": "performed",
"redirect_url": "https://example.com",
"fallback_url": "https://example.org",
"details": {
"title": "Some title",
"status": "active"
}
}
HTTP Request
GET https://portal-api.brandactif.com/api/v2/scans/<UUID>
URL Parameters
Parameter | Description |
---|---|
UUID |
the UUID of the scan to retrieve |
Response
In most cases, you will get a 200 OK
HTTP response with following parameters:
Parameter | Description |
---|---|
uuid |
UUID of your scan |
status |
status of image processing; can be one of following:
|
redirect_url |
if your image is matched with a reference image in our database, you get an URL you redirect user to |
fallback_url |
if your image is not matched with any reference image, you get a fallback URL you redirect user to (if set by brand; null otherwise) |
details |
if your image is matched with a reference image in our database, you get a hash with details to redirect your user within your native app |
In case the scanning proccess is still in the queue, you may get a 404 Not Found
response. Even though it's highly unlikely situation to happen, you should handle this and continue to fetch for scan data until you get 200 OK
response.
PWA custom domain
This section describes how to enable a custom domain for your PWA app with SSL support.
Let's assume your domain is: example.org and you want your PWA app to be accessed at: tap.example.org.
- First you need to send us your desired subdomain i.e. tap.example.org.
- You will get CNAME entries from us that you need to set in your domain provider panel. There will be 2 entries.
- first entry will be a
CNAME
record that associates your domain tap.example.org with our application example.brandactif.com (see App record snippet)
App record
# Required for the app itself:
# You will add `tap` subdomain to your `example.org` domain that points to our application:
#
tap CNAME example.brandactif.com.
- another entry will also be a
CNAME
record that points to a validation domain (see Validation record snippet)
Validation record
# Required for SSL validation
#
_XXXXX.tap CNAME _YYYYY.ZZZZZ.acm-validations.aws.
Once set we need to wait up to 48h for DNS propagation.
- When DNS is finally set we can configure the rest of the app and associate your subdomain with our app.
Google Analytics
If you want to use Google Analytics in your PWA app, you need only to provide us with a GA token.
Radio taps
Example request
curl --request POST \
--url https://portal-api.brandactif.com/api/v2/radio_scans/ \
--header 'api-key: d5b3af44cd0f967e9f4218a4131d85ec522cc865a246fa23792a8f3836f21caf' \
--header 'content-type: application/json' \
--data '{
"radio_scan": {
"radio_name": "Channel 1",
"time": "2020-03-02T15:40:00+0100",
"latitude": 52.237049,
"longitude": 21.017532,
"metadata": {
"browser": "Chrome",
"language": "en-GB"
}
}
}'
The above request returns JSON with the following structure:
{
"redirect_url": "https://brandactif.com",
"response_details": {
"foo": "bar"
}
}
HTTP Request
POST https://portal-api.brandactif.com/api/v2/radio_scans
Body parameters
Body
Parameter | Type | Required | Description |
---|---|---|---|
radio_scan |
object | true | object containing radio scan details |
Body/radio_scan
Parameter | Type | Required | Description |
---|---|---|---|
radio_name |
string | true | name of the radio to match |
time |
string | true | ISO8601 formatted string representing date and time |
latitude , longitude |
float | false | coordinates of the device performing a radio scan |
metadata |
object | false | JSON object with additional parameters of the device performing a radio scan |
Response
201 Created
HTTP response with following parameters:
Parameter | Description |
---|---|
redirect_url |
returned if URL is set for given time range and radio name; null otherwise |
response_details |
returned if response details are set for given time range and radio name; empty JSON object otherwise |
TV taps
Example request
curl --request POST \
--url https://portal-api.brandactif.com/api/v2/tv_scans/ \
--header 'api-key: d5b3af44cd0f967e9f4218a4131d85ec522cc865a246fa23792a8f3836f21caf' \
--header 'content-type: application/json' \
--data '{
"tv_scan": {
"tv_name": "Channel 1",
"time": "2020-03-02T15:40:00+0100",
"latitude": 52.237049,
"longitude": 21.017532,
"metadata": {
"browser": "Chrome",
"language": "en-GB"
}
}
}'
The above request returns JSON with the following structure:
{
"redirect_url": "https://brandactif.com",
"response_details": {
"foo": "bar"
}
}
HTTP Request
POST https://portal-api.brandactif.com/api/v2/tv_scans
Body parameters
Body
Parameter | Type | Required | Description |
---|---|---|---|
tv_scan |
object | true | object containing TV scan details |
Body/tv_scan
Parameter | Type | Required | Description |
---|---|---|---|
tv_name |
string | true | name of the TV to match |
time |
string | true | ISO8601 formatted string representing date and time |
latitude , longitude |
float | false | coordinates of the device performing a TV scan |
metadata |
object | false | JSON object with additional parameters of the device performing a TV scan |
Response
201 Created
HTTP response with following parameters:
Parameter | Description |
---|---|
redirect_url |
returned if URL is set for given time range and TV name; null otherwise |
response_details |
returned if response details are set for given time range and TV name; empty JSON object otherwise |
Video taps
Example request
curl --request POST \
--url https://portal-api.brandactif.com/api/v2/video_scans/ \
--header 'api-key: d5b3af44cd0f967e9f4218a4131d85ec522cc865a246fa23792a8f3836f21caf' \
--header 'content-type: application/json' \
--data '{
"video_scan": {
"video_name": "Example movie",
"time": 40.75,
"latitude": 52.237049,
"longitude": 21.017532,
"metadata": {
"browser": "Chrome",
"language": "en-GB"
}
}
}'
The above request returns JSON with the following structure:
{
"redirect_url": "https://brandactif.com",
"response_details": {
"foo": "bar"
}
}
HTTP Request
POST https://portal-api.brandactif.com/api/v2/video_scans
Body parameters
Body
Parameter | Type | Required | Description |
---|---|---|---|
video_scan |
object | true | object containing video scan details |
Body/video_scan
Parameter | Type | Required | Description |
---|---|---|---|
video_name |
string | true | name of the video to match |
time |
float | true | time of the video (measured in seconds) |
latitude , longitude |
float | false | coordinates of the device performing a video scan |
metadata |
object | false | JSON object with additional parameters of the device performing a video scan |
Response
201 Created
HTTP response with following parameters:
Parameter | Description |
---|---|
redirect_url |
returned if URL is set for given time range and video name; null otherwise |
response_details |
returned if response details are set for given time range and video name; empty JSON object otherwise |
Get time ranges
Example request
curl --request GET \
--url https://portal-api.brandactif.com/api/v2/video_time_ranges?video_name=Example%20movie \
--header 'api-key: d5b3af44cd0f967e9f4218a4131d85ec522cc865a246fa23792a8f3836f21caf'
The above request returns JSON with the following structure:
[
{
"start_at": 40.25,
"end_at": 50.75,
"program_name": "Program 1"
},
{
"start_at": 60.25,
"end_at": 70.75,
"program_name": "Program 2"
}
]
HTTP Request
GET https://portal-api.brandactif.com/api/v2/video_time_ranges?video_name=<NAME>
Query parameters
Parameter | Type | Required | Description |
---|---|---|---|
video_name |
string | true | name of the video to match |
Response
200 OK
HTTP response with a list of video time ranges
Errors
The Brandactif API uses the following error codes:
Error Code | Meaning |
---|---|
400 | Bad Request -- Your request is invalid (e.g. some of the required params are missing). |
401 | Unauthorized -- Your API key is wrong or missing. |
404 | Not Found -- The specified resource could not be found. |
418 | I'm a teapot. |
500 | Internal Server Error -- We had a problem with our server. Try again later. |
503 | Service Unavailable -- We're temporarily offline for maintenance. Please try again later. |