Every feature of Protobi that can be accessed via the web user interface can also be accessed programmatically via the Protobi REST API. 

Protobi is a rich client app, so all detailed GUI actions can also be done dynamically within the browser using the Protobi JavaScript API.pdf

This tutorial describes REST API calls to the Protobi server. If you're reading this article it's likely you're an advanced user with programming knowledge. If you need more assistance contact us at support@protobi.com.

The Protobi REST API can be called from any web interface, including browsers, Node.js, R, Python etc. Examples here are shown using jQuery.

There is also a Node.js SDK which simplifies these calls.

Overview

There are many routes which cover detailed actions like setting project title and images, user permissions, usage logs and change histories.

However, the primary routes you will likely call in practice are to get/set the data as a CSV string, and the elements configuration as a JSON array.

Protobi stores each project as two data elements:

  • CSV data file
  • JSON elements description

The CSV data file is a string in standard CSV format (see IETF 4180 spec). The Elements configuration is an array of element objects.

Authentication

You can call the REST API using your Protobi API Key.
This API key is appended to each URL call as a query parameter, e.g. ?apiKey=.

To get your API key, go to your Protobi account page at https://app.protobi.com/account and press the "Generate API Key" button. Keep this key secret, it allows the holder to login to your account as you.

Create project

  • Method: POST
  • URL:  /api/v3/dataset?apiKey=
  • @returns:  Project info in JSONformat

Example  

var url = `${BASE_URL}/api/v3/dataset?apiKey=${API_KEY}`;
var content = {
  name: "Lorem ipsum dolor sit amet",
  title: "Consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
  description: "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
  logo_url: "https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcR6ChKkOeEbcxejhaz4exEqLpuob2tbyOjgfAv-MgQ8tBxITsyB",
  image_url: null,
  primary_table: 'main',
  url: "https://loremipsum.com",
  properties: {
    "foo": "bar"
  }
}

request({ url: url, method: "POST", body: content, json: true, }, function (err, response, body) {...})

Delete project

  • Method: DELETE
  • URL:  /api/v3/dataset/?apiKey=
  • @returns:  Project info in JSONformat

Example  

var url = `${BASE_URL}/api/v3/dataset/${datasetId}?apiKey=${API_KEY}`;


request({ url: url, method: "DELETE" }, function (err, response, body) {...})

Upload data file

Upload a CSV or SAV as a data file:

  • Method: POST
  • URL: /api/v3/dataset//data/
  • @queryparam  datasetId
  • @queryparam key
  • @bodyparam type  String, e.g. "data"
  • @bodyparam filename, String

Send the file as an attachment, either a CSV file with content type "test/csv" or an SPSS SAV file with content type "application/x-spss-sav"

Example (Node.js)

var url = `${BASE_URL}/api/v3/dataset/${DATASET_ID}/data/${DATA_KEY}?apiKey=${API_KEY}`;
var readStream = fs.createReadStream(filename, {highWaterMark: 500});

var req = request({ method: "POST", url: url, }, function (err, response, body) {...})

var form = req.form(); form.append('type', 'data') form.append('file', readStream, { filename: filename, contentType: 'application/x-spss-sav' });

Example (Python)

import requests
BASE_URL='https://app.protobi.com'
url = '{BASE_URL}/v3/datasets/{DATASET_ID}/data/{DATA_KEY}?apiKey={API_KEY}'
filename = 'responses.sav'
filepath = '../test/data/responses.sav'
files = {
  'file':(filename, open(filepath, 'rb'))
}
req = requests.post(url + '?' + apiKey,  files=files  )

Example (jQuery)

var fd = new FormData();
fd.append('file', new File([new Blob([csv])], filename));

$.ajax({ url: url, data: fd, processData: false, contentType: 'text/csv', type: 'POST', success: console.log, error: console.error });

Upload Confirmit XML file

  • Method: POST
  • URL: /api/v3/dataset//data/
  • @queryparam  datasetId
  • @queryparam key
  • @bodyparam type  String, specifically "data"
  • @bodyparam filename, String e.g. "confirmit.xml"

Send the file as an attachment with key "confirmit.xml"

Example

var url = `${BASE_URL}/api/v3/dataset/${datasetId}/data/${key}.xml?apiKey=${API_KEY}`;
var readStream = fs.createReadStream(filename, {highWaterMark: 500});

var req = request({ method: "POST", url: url, }, function (err, response, body) {...})

var form = req.form(); form.append('type', 'data') form.append('file', readStream, { filename: filename, contentType: 'text/xml' });

Apply Confirmit XML file

  • Method: POST
  • URL: /api/v3/dataset//layout/
  • @queryparam  datasetId
  • @queryparam key

Send the file as an attachment with key "confirmit.xml"

Example

var key = "confirmit.xml"
var url = `${BASE_URL}/api/v3/dataset/${datasetId}/layout/${key}?apiKey=${API_KEY}`

request({ method: "POST", url: url, }, function (err, response, body) {...})

Add permitted user

  • Method: POST
  • URL: /api/v3/dataset//permission/
  • @bodyparam  email (String) 
  • @bodyparam  permission (String), either "view", "edit", "admin" or "none"

Example

var url = `${BASE_URL}/api/v3/dataset/${datasetId}/permission/?apiKey=${API_KEY}`;
var content = {
  email: "test.testerson@test.com",
  role: "edit"
}

request({ url: url, method: "POST", body: content, json: true,

},
function (err, response, body) {...})</pre><h2 data-toc="true" id="get-permitted-users-16">Get permitted users</h2><ul>
  • Method: GET
  • URL: /api/v3/dataset//permission
  • Example

    var url = `${BASE_URL}/api/v3/dataset/${datasetId}/permission?apiKey=${API_KEY}`;
    
    

    request({ url: url, method: "GET", json: true }, function (err, response, body) {...})

    Download elements

    • Method: GET
    • URL: /v3/datasets/:datasetId/element
    • @param: datasetId unique identifier for dataset
    • @returns: Elements configuration in JSONformat

    Example (jQuery):

    $.ajax({
        type: "GET",
        dataType: "json",
        url: "/api/v3/dataset//element",
        success: function (csv, status, xhr) {
            ...
        },
        error: function (xhr, status, err) {
            ...
        }
    })

    Example (Node.js)

    Upload elements

    • Method: POST
    • URL: //v3/datasets/:datasetId/element
    • @param: datasetId unique identifier for dataset
    • @returns: Elements configuration in JSON forre

    Example (jQuery):

      $.ajax({
            type: "POST",
            url: "/api/v3/dataset//element",
            dataType: "json",
            contentType: 'application/json',
            data: JSON.stringify(elements),
            success: function (data, status, xhr) {
                ...
            },
            error: function (xhr, status, err) {
                ...
            }
      })

    Download data file

    • Method: GET
    • URL: //v3/datasets/:datasetId/data/:key/:type
    • @param: datasetId unique identifier for dataset
    • @param: key data key, e.g. 'main'
    • @param: type, e.g. csv, sav, or raw to return the original file.
    • @returns: Data file in CSV text format

    Example (jQuery):

    $.ajax({
        type: "GET",
        url: "/api/v3/dataset/<datasetId>/data/?apiKey=",
        success: function (csv, status, xhr) {
            ...
        },
        error: function (xhr, status, err) {
            ...
        }
    })

    Helper libraries for R and Node.js

    You can use Protobi R package https://github.com/protobi/protobi-r which wraps the REST API and reads Protobi data into and from R data frames, and represents value labels as factors:

    data <- protobi.get_data(PROJECTID, TABLEKEY, APIKEY)
    protobi.put_data(data, PROJECTID, TABLEKEY, APIKEY)
    `

    There is also a Node.js library https://github.com/protobi/protobi-node-sdk which wraps the REST API for calls from Node.js servers or scripts:

    protobiAPI.uploadData(data, PROTOBI_PROJECT_ID, "main", null, function (err) {
      if (err) return callback(err);
      console.log("DATA uploaded")
    })