NAV Navbar
shell ruby

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:

  1. Get a S3 presigned URL and upload an image
  2. Create the scan in our database
  3. 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:

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:
  • initial - initial status of a scan,
  • uploading_to_aws - when the process of uploading an image file to S3 is in progress,
  • uploaded_to_aws - when the process of uploading an image file to S3 is finished,
  • performing - when the process of matching scan image is in progress,
  • performed - when the process of matching scan image is finished; this is the final status of the succesful scanning process,
  • failed_upload_to_aws - when the process of uploading an image file to S3 failed,
  • failed_to_perform - when the process of matching scan image failed
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.

  1. First you need to send us your desired subdomain i.e. tap.example.org.
  2. You will get CNAME entries from us that you need to set in your domain provider panel. There will be 2 entries.

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.

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.

  1. 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.