zenloop Developer Hub

Welcome to the zenloop developer hub. You'll find comprehensive documentation to help you start working with zenloop as quickly as possible, as well as support if you get stuck. Happy looping!

Get Started    
Suggest Edits

Introduction

The zenloop API is organized around REST

You can currently use our API to perform two main sets of tasks (other than authentication):

  1. Sending out a survey using "our email" channel (including adding recipients, properties and metatags)
  2. Getting data about a survey or surveys (including getting answers and scores)

Our API can be found at https://api.zenloop.com

 

Getting started

A quick guide to getting your API setup, and testing to make sure recipients are being successfully added

  1. Authenticate your account
  2. Pick the survey you want to use the API for, or create a new survey to test. Don’t launch the survey (or pause it so that the status is draft or off). This will prevent the survey sending out emails (it will stockpile them)
  3. Add recipients using API or use our Bulk API upload
    Optional: use these endpoint to add properties or metatags
  4. You can check if the recipients were successfully added in the web interface, under the recipients step for that survey
Suggest Edits

Authentication

This endpoint is used for obtaining user information and token for API requests authentication.

 
posthttps://api.zenloop.com/v1/sessions
curl --request POST \
  --url https://api.zenloop.com/v1/sessions \
  --header 'content-type: application/json'
var request = require("request");

var options = { method: 'POST',
  url: 'https://api.zenloop.com/v1/sessions',
  headers: { 'content-type': 'application/json' } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
require 'uri'
require 'net/http'

url = URI("https://api.zenloop.com/v1/sessions")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'

response = http.request(request)
puts response.read_body
var data = JSON.stringify(false);

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://api.zenloop.com/v1/sessions");
xhr.setRequestHeader("content-type", "application/json");

xhr.send(data);
import requests

url = "https://api.zenloop.com/v1/sessions"

headers = {'content-type': 'application/json'}

response = requests.request("POST", url, headers=headers)

print(response.text)
A binary file was returned

You couldn't be authenticated

{
  "user": {
    "id": 1,
    "first_name": "Joe",
    "last_name": "Doe",
    "email": "joe@doe.com",
    "language_id": 2,
    "organization_id": 1,
    "country": "England"
  },
  "session": {
    "jwt": "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9",
    "exp": 1477577414
  }
}
{
  "error": {
    "status": 400,
    "code": "INVALID_REQUEST",
    "links": {
      "documentation": "https://docs.zenloop.com/v1.0/reference#authentication"
    },
    "title": "Invalid request body.",
    "details": [
      {
        "detail": "Required property email was not present.",
        "pointer": "/user"
      },
      {
        "detail": "Required property password was not present.",
        "pointer": "/user"
      }
    ]
  }
}
{
  "error": {
    "status": 401,
    "code": "UNAUTHORIZED",
    "title": "Incorrect email or password."
  }
}
{
  "error": {
    "status": 429,
    "code": "TOO_MANY_REQUESTS",
    "title": "Authentication limit exceeded."
  }
}

Body Params

user
object
required

User authentication data

 
user.email
string
required

User email address

user.password
string
required

User password

Headers

Content-Type
string
required
 
{
  "user": {
    "email": "test@test.com",
    "password": "password"
  }
}

Response attributes

Attribute Type Description
user object User information data.
user.id number User identifier.
user.first_name string User first name.
user.last_name string User last name.
user.email string User email address.
user.organization_id number User organization identifier.
user.language_id number User language identifier.
user.country string User country name.
session object Session information data.
session.jwt string Authentication token.
session.exp string Token expiration date.

Authorization header

You will need to store the token so that you can use it in further requests. Pass it in the Authorization header in requests to API:
Authorization: Bearer <token>

400 Bad Request - Invalid request

{
  "error": {
    "status": 400,
    "code": "INVALID_REQUEST",
    "links": {
      "documentation": "https://docs.zenloop.com/#authentication"
    },
    "title": "Invalid request body.",
    "details": [
      {
        "detail": "Required property email was not present.",
        "pointer": "/user"
      },
      {
        "detail": "Required property password was not present.",
        "pointer": "/user"
      }
    ]
  }
}
Attribute Type Description
error object Error object.
error.status number Status code.
error.code string Error code.
error.links object Links object.
error.links.documentation string URL link to documentation.
error.title string Error title.
error.details array List with error details.
error.details.pointer string Pointer to specific attribute.
error.details.detail string Error message for pointer.

400 Bad Request - Validation errors

{
  "error": {
    "status": 400,
    "code": "VALIDATION_ERRORS",
    "title": "Validation errors occurred.",
    "details": [
      {
        "detail": "has invalid format",
        "field": "email"
      }
    ]
  }
}
Attribute Type Description
error object Error object.
error.status number Status code.
error.code string Error code.
error.title string Error title.
error.details array List with error details.
error.details.field string Field name.
error.details.detail string Error message for pointer.

401 Unauthorized

{
  "error": {
    "status": 401,
    "code": "UNAUTHORIZED",
    "title": "Invalid or expired token.",
  }
}
Attribute Type Description
error object Error object.
error.status number Status code.
error.code string Error code.
error.title string Error title.

403 Forbidden

{
  "error": {
    "status": 403,
    "code": "FORBIDDEN",
    "title": "Access denied."
  }
}
Attribute Type Description
error object Error object.
error.status number Status code.
error.code string Error code.
error.title string Error title.

404 Not Found

{
  "error": {
    "status": 404,
    "code": "NOT_FOUND",
    "title": "Survey not found.",
  }
}
Attribute Type Description
error object Error object.
error.status number Status code.
error.code string Error code.
error.title string Error title.

409 Conflict

{
  "error": {
    "status": 409,
    "code": "ALREADY_EXISTS",
    "title": "Recipient already exists.",
  }
}
Attribute Type Description
error object Error object.
error.status number Status code.
error.code string Error code.
error.title string Error title.

429 Too Many Requests

{
  "error": {
    "status": 429,
    "code": "TOO_MANY_REQUESTS",
    "title": "Rate limit exceeded.",
  }
}
Attribute Type Description
error object Error object.
error.status number Status code.
error.code string Error code.
error.title string Error title.
Suggest Edits

Add External Recipient

This is the endpoint used for adding recipients to a survey. It has a limitation of 1000 requests per minute which is reset every minute (at 00:00, not 60 seconds after the last request). Valid Survey id for existing survey needs to be provided.

We automatically filter out duplicate emails and prevent the same email being uploaded and sent more than once every 10 minutes.

If you need to add a large batch of recipients at once, see our documentation for Bulk API

If adding metatags by score type (e.g. thank_you_note_promoter, thank_you_note_passive, thank_you_note_detractor) they will work only if 'Customise based on score' switch is enabled within the web interface (on the design step of the survey).

For thank_you_link_url and thank_you_link_note to work, you will also need to enable the 'Add a link' switch in the web interface.

Using this endpoint, you can also include properties and metatags

 

Header Auth

 Authentication is required for this endpoint.
posthttps://api.zenloop.com/v1/surveys/survey_id/survey_recipients
curl --request POST \
  --url https://api.zenloop.com/v1/surveys/survey_id/survey_recipients \
  --header 'authorization: Bearer <token>' \
  --header 'content-type: application/json'
var request = require("request");

var options = { method: 'POST',
  url: 'https://api.zenloop.com/v1/surveys/survey_id/survey_recipients',
  headers: 
   { 'content-type': 'application/json',
     authorization: 'Bearer <token>' } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
require 'uri'
require 'net/http'

url = URI("https://api.zenloop.com/v1/surveys/survey_id/survey_recipients")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["authorization"] = 'Bearer <token>'
request["content-type"] = 'application/json'

response = http.request(request)
puts response.read_body
var data = JSON.stringify(false);

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://api.zenloop.com/v1/surveys/survey_id/survey_recipients");
xhr.setRequestHeader("authorization", "Bearer <token>");
xhr.setRequestHeader("content-type", "application/json");

xhr.send(data);
import requests

url = "https://api.zenloop.com/v1/surveys/survey_id/survey_recipients"

headers = {
    'authorization': "Bearer <token>",
    'content-type': "application/json"
    }

response = requests.request("POST", url, headers=headers)

print(response.text)
A binary file was returned

You couldn't be authenticated

{
  "survey_recipient": {
    "id": "b3M5bTNjV0dSTEdoZU9xb2t3WTRwZjhsQzUya0lMaGgycWVUNmZWZ1pJTT0=",
    "status": "created",
    "recipient": {
      "id": "YzloYlJmL3NaZ21FVk5GVUdiS1NLZGQ5ODZ0ekF1Z0o1WDdSRld6b2xwTT0=",
      "email": "recipient@test.com",
      "first_name": "test_first_name",
      "last_name": "test_last_name",
      "upload_status": "new"
    },
    "survey": {
      "id": "eGRiMFIweVc1UDYyMmVBZkRPWnlZdTh0cVBKY2J0TjBaYm0xOXdZRjhpdz0=",
      "title": "My survey",
      "status": "active"
    },
    "properties": [
      {
        "name": "country",
        "value": "Germany"
      },
      {
        "name": "gender",
        "value": "male"
      }
    ],
    "metatags": {
      "survey_question": "How likely are you to recommend %[question subject] test_first_name?",
      "question_subject": "metatags",
      "request_for_comment_promoter": "Tell us why you chose %[score] as metatags score, promoter",
      "request_for_comment_passive": "Tell us why you chose %[score] as metatags score, passive",
      "request_for_comment_detractor": "Tell us why you chose %[score] as metatags score, detractor",
      "thank_you_note_promoter": "Thanks for your feedback promoting metatags!",
      "thank_you_note_passive": "Thanks for your feedback about metatags!",
      "thank_you_note_detractor": "Thanks for your feedback not promoting metatags!",
      "thank_you_link_url_promoter": "http://www.zenloop.com",
      "thank_you_link_url_detractor": "http://www.facebook.com",
      "thank_you_link_url_passive": "http://www.example.com",
      "thank_you_link_text_promoter": "Metatags Promoter",
      "thank_you_link_text_passive": "Metatags Passive",
      "thank_you_link_text_detractor": "Metatags Detractor"
    }
  }
}
{
  "error": {
    "status": 400,
    "code": "INVALID_REQUEST",
    "links": {
      "documentation": "https://docs.zenloop.com/v1.0/reference"
    },
    "title": "Invalid request body.",
    "details": [{
      "detail": "Required property recipient was not present.",
      "pointer": ""
    }]
  }
}
{
  "error": {
    "status": 400,
    "code": "VALIDATION_ERRORS",
    "title": "Validation errors occurred.",
    "details": [{
      "detail": "We can't duplicate survey recipients",
      "field": "survey_recipient"
    }]
  }
}
{
  "error": {
    "status": 401,
    "code": "UNAUTHORIZED",
    "title": "Invalid or expired token."
  }
}
{
  "error": {
    "status": 403,
    "code": "FORBIDDEN",
    "title": "Action forbidden. Only allowed for email survey."
  }
}
{
  "error": {
    "status": 404,
    "code": "NOT_FOUND",
    "title": "Survey not found."
  }
}
{
  "error": {
    "status": 429,
    "code": "TOO_MANY_REQUESTS",
    "title": "Rate limit exceeded."
  }
}

Path Params

survey_id
string
required

Unique ID of a survey

Body Params

recipient
object
 
recipient.email
string
required

Recipient email address.

recipient.first_name
string

Recipient first name.

recipient.last_name
string

Recipient last name.

recipient.properties
array of objects

List of properties.

name
value
recipient.metatags
object

List of metatags

 
recipient.metatags.survey_question
string

New question for the survey.

recipient.metatags.question_subject
string

New subject for survey question.

recipient.metatags.thank_you_note_all
string

New message for thank you page.

recipient.metatags.thank_you_note_promoter
string

New message for thank you page for promoter score if thank you by score is enabled.

recipient.metatags.thank_you_note_passive
string

New message for thank you page for passive score if thank you by score is enabled.

recipient.metatags.thank_you_note_detractor
string

New message for thank you page for detractor score if thank you by score is enabled.

recipient.metatags.thank_you_link_url_all
string

New url for thank you page link.

recipient.metatags.thank_you_link_url_promoter
string

New url for thank you page link for promoter score if thank you link by score is enabled.

recipient.metatags.thank_you_link_url_passive
string

New url for thank you page link for passive score if thank you link by score is enabled.

recipient.metatags.thank_you_link_url_detractor
string

New url for thank you page link for detractor score if thank you link by score is enabled.

recipient.metatags.thank_you_link_text_all
string

New text for thank you page link.

recipient.metatags.thank_you_link_text_promoter
string

New text for thank you page link for promoter score if thank you link by score is enabled.

recipient.metatags.thank_you_link_text_passive
string

New text for thank you page link for passive score if thank you link by score is enabled.

recipient.metatags.thank_you_link_text_detractor
string

New text for thank you page link for detractor score if thank you link by score is enabled.

recipient.metatags.request_for_comment_all
string

New message on comment page.

recipient.metatags.request_for_comment_promoter
string

New message on comment page for promoter score if comment by score is enabled.

recipient.metatags.request_for_comment_passive
string

New message on comment page for passive score if comment by score is enabled.

recipient.metatags.request_for_comment_detractor
string

New message on comment page for detractor score if comment by score is enabled.

Headers

Authorization
string
required
Content-Type
string
required
 

You can only add recipients using our API to our email survey

{
  "recipient": {
    "email": "recipient@test.com",
    "first_name": "test_first_name",
    "last_name": "test_last_name",
    "properties": [
      {"name": "country", "value": "Germany"},
      {"name": "gender", "value": "male"}
    ],
    "metatags": {
      "survey_question": "How likely are you to recommend %[question subject] test_first_name?",
      "question_subject": "metatags",
      "request_for_comment_all": "Tell us a bit more about why you chose %[score] for metatags",
      "thank_you_link_text_all": "example text",
      "thank_you_link_url_all": "www.example.com",
      "thank_you_note_all": "Thanks for your feedback!"
    }
  }
}

Response attributes

Attribute Type Description
survey_recipient object Survey recipient information data.
survey_recipient.id string Survey recipient id.
survey_recipient.status string Survey recipient status.
survey_recipient.recipient object Recipient information data.
survey_recipient.recipient.id string Recipient id.
survey_recipient.recipient.email string Recipient email.
survey_recipient.recipient.first_name string Recipient first name.
survey_recipient.recipient.last_name string Recipient last_name.
survey_recipient.recipient.upload_status status Recipient status. One of: new, found
survey_recipient.survey.id string Survey id.
survey_recipient.survey.title string Survey title.
survey_recipient.survey.status string Survey status.
survey_recipient.properties array List of properties.
survey_recipient.properties.name string Name of the property.
survey_recipient.properties.value string Value of the property.
survey_recipient.metatags.survey_question string Question of the survey containing reference to question_subject.
survey_recipient.metatags.question_subject string Subject of the question.
survey_recipient.metatags.request_for_comment_all string Text for comment page regardless of survey recipient score.
survey_recipient.metatags.request_for_comment_promoter string Text for comment page for promoters.
survey_recipient.metatags.request_for_comment_passive string Text for comment page for passives.
survey_recipient.metatags.request_for_comment_detractor string Text for comment page for detractors.
survey_recipient.metatags.thank_you_note_all string Text for thank you page regardless of survey recipient score.
survey_recipient.metatags.thank_you_note_promoter string Text for thank you page for promoters.
survey_recipient.metatags.thank_you_note_passive string Text for thank you page for passives.
survey_recipient.metatags.thank_you_note_detractor string Text for thank you page for detractors.
survey_recipient.metatags.thank_you_link_text_all string Text for link on thank you page regardless of survey recipient score.
survey_recipient.metatags.thank_you_link_text_promoter string Text for link on thank you page for promoters.
survey_recipient.metatags.thank_you_link_text_passive string Text for link on thank you page for passives.
survey_recipient.metatags.thank_you_link_text_detractor string Text for link on thank you page for detractors.
survey_recipient.metatags.thank_you_link_url_all string URL for link on thank you page regardless of survey recipient score.
survey_recipient.metatags.thank_you_link_url_promoter string URL for link on thank you page for promoters.
survey_recipient.metatags.thank_you_link_url_passive string URL for link on thank you page for passives.
survey_recipient.metatags.thank_you_link_url_detractor string URL for link on thank you page for detractors.
Suggest Edits

Add Bulk External Recipients

This is the endpoint used for adding larger batches of recipients to a survey. It has a limitation of 1000 requests per minute which is being reset every minute. Valid Survey id for existing survey needs to be provided.

We automatically filter out duplicate emails and prevent the same email being uploaded and sent more than once every 10 minutes.

If adding metatags by score type (e.g. thank_you_note_promoter, thank_you_note_passive, thank_you_note_detractor) they will work only if 'Customise based on score' switch is enabled within the web interface (on the design step of the survey).

For thank_you_link_url and thank_you_link_note to work, you will also need to enable the 'Add a link' switch in the web interface.

Using this endpoint, you can also include properties and metatags

 

Header Auth

 Authentication is required for this endpoint.
posthttps://api.zenloop.com/v1/bulk/survey_recipients
curl --request POST \
  --url https://api.zenloop.com/v1/bulk/survey_recipients \
  --header 'authorization: Bearer <token>' \
  --header 'content-type: application/json'
var request = require("request");

var options = { method: 'POST',
  url: 'https://api.zenloop.com/v1/bulk/survey_recipients',
  headers: 
   { 'content-type': 'application/json',
     authorization: 'Bearer <token>' } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
require 'uri'
require 'net/http'

url = URI("https://api.zenloop.com/v1/bulk/survey_recipients")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["authorization"] = 'Bearer <token>'
request["content-type"] = 'application/json'

response = http.request(request)
puts response.read_body
var data = JSON.stringify(false);

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://api.zenloop.com/v1/bulk/survey_recipients");
xhr.setRequestHeader("authorization", "Bearer <token>");
xhr.setRequestHeader("content-type", "application/json");

xhr.send(data);
import requests

url = "https://api.zenloop.com/v1/bulk/survey_recipients"

headers = {
    'authorization': "Bearer <token>",
    'content-type': "application/json"
    }

response = requests.request("POST", url, headers=headers)

print(response.text)
A binary file was returned

You couldn't be authenticated

{
  "status": "Request queued."
}
{
  "status": 400,
  "title": "Invalid request body.",
  "links": {
    "documentation": "https://docs.zenloop.com/v1.0/reference#add-external-recipients"
  },
  "code": "INVALID_REQUEST",
  "details": [{
    "detail": "Expected a minimum of 1 items but got 0.",
    "pointer": "/recipients"
  }]
}
{
  "error": {
    "status": 401,
    "code": "UNAUTHORIZED",
    "title": "Invalid or expired token."
  }
}
{
  "error": {
    "status": 403,
    "code": "FORBIDDEN",
    "title": "Action forbidden. Only allowed for email survey."
  }
}
{
  "error": {
    "status": 404,
    "code": "NOT_FOUND",
    "title": "Survey not found."
  }
}
{
  "error": {
    "status": 429,
    "code": "TOO_MANY_REQUESTS",
    "title": "Rate limit exceeded."
  }
}

Body Params

survey_id
string
required

Unique ID of a survey.

survey_recipients
array of objects
required

List of recipients.

recipient.email
recipient.first_name
recipient.last_name
recipient.properties
recipient.metatags 

Headers

Authorization
string
required
Content-Type
string
required
 

You can only add recipients using our API to our email survey

{
  "survey_id": "RXpqTHZLTVNYU29nQnNzQ3V1VVgveEdmNTJTK2VheXNt",
  "survey_recipients": [
    {
      "recipient": {
        "email": "recipient@test.com",
        "first_name": "test_first_name",
        "last_name": "test_last_name",
        "properties": [
          {"name": "country", "value": "Germany"},
          {"name": "gender", "value": "male"}
        ],
        "metatags": {
          "survey_question": "How likely are you to recommend %[question subject] test_first_name?",
          "question_subject": "metatags",
          "request_for_comment_all": "Tell us a bit more about why you chose %[score] for metatags",
          "thank_you_link_text_all": "example text",
          "thank_you_link_url_all": "www.example.com",
          "thank_you_note_all": "Thanks for your feedback!"
        }
      }
    },
    {
      "recipient": {
        "email": "recipient2@test.com",
        "first_name": "test_first_name2",
        "last_name": "test_last_name2",
        "properties": [
          {"name": "country", "value": "Germany"},
          {"name": "gender", "value": "male"}
        ],
        "metatags": {
          "survey_question": "How likely are you to recommend %[question subject] test_first_name?",
          "question_subject": "metatags",
          "request_for_comment_all": "Tell us a bit more about why you chose %[score] for metatags",
          "thank_you_link_text_all": "example text",
          "thank_you_link_url_all": "www.example.com",
          "thank_you_note_all": "Thanks for your feedback!"
        }
      }
    }
  ]
}

Response attributes

Attribute Type Description
status string Request status.
Suggest Edits

Get Answers

This endpoint is used for fetching survey answers along with basic survey data and aggregated NPS scores.

 

Header Auth

 Authentication is required for this endpoint.
gethttps://api.zenloop.com/v1/surveys/survey_id/answers
curl --request GET \
  --url https://api.zenloop.com/v1/surveys/survey_id/answers \
  --header 'authorization: Bearer <token>' \
  --header 'content-type: application/json'
var request = require("request");

var options = { method: 'GET',
  url: 'https://api.zenloop.com/v1/surveys/survey_id/answers',
  headers: 
   { 'content-type': 'application/json',
     authorization: 'Bearer <token>' } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
require 'uri'
require 'net/http'

url = URI("https://api.zenloop.com/v1/surveys/survey_id/answers")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["authorization"] = 'Bearer <token>'
request["content-type"] = 'application/json'

response = http.request(request)
puts response.read_body
var data = JSON.stringify(false);

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://api.zenloop.com/v1/surveys/survey_id/answers");
xhr.setRequestHeader("authorization", "Bearer <token>");
xhr.setRequestHeader("content-type", "application/json");

xhr.send(data);
import requests

url = "https://api.zenloop.com/v1/surveys/survey_id/answers"

headers = {
    'authorization': "Bearer <token>",
    'content-type': "application/json"
    }

response = requests.request("GET", url, headers=headers)

print(response.text)
A binary file was returned

You couldn't be authenticated

{
  "survey": {
    "title": "After Checkout DE",
    "status": "active",
    "response_rate": "N/A",
    "public_hash_id": "RWVJTzN3MkJTSklMMEUxMFVJdm5VN1hEZVIvWnhpZ1lGdEZ3a25ET25tWT0=",
    "promoters": {
      "percentage": 50,
      "delta": 0
    },
    "passives": {
      "percentage": 25,
      "delta": 0
    },
    "number_of_responses": 4,
    "nps": {
      "percentage": 25,
      "delta": 0
    },
    "inserted_at": "2017-01-26T12:31:44Z",
    "detractors": {
      "percentage": 25,
      "delta": 0
    }
  },
  "properties": [
    {"value": "germany", "name": "country", "id": 2},
    {"value": "blue", "name": "color", "id": 6},
    {"value": "uk", "name": "country", "id": 4},
    {"value": "white", "name": "color", "id": 7},
    {"value": "1350", "name": "value", "id": 12},
    {"value": "GBP", "name": "currency", "id": 14},
    {"value": "france", "name": "country", "id": 3},
    {"value": "green", "name": "color", "id": 8},
    {"value": "1000", "name": "value", "id": 9},
    {"value": "EUR", "name": "currency", "id": 13}
  ],
  "meta": {
    "total": 4,
    "survey_has_answers": true,
    "per_page": 20,
    "page": 1
  },
  "answers": [
    {
      "id": "NVdYMTRPOVZnb0NmeWhTUVljMmplR2p6MS9kTTBFem4vZ1VGZDJ5WVhycz0=",
      "score_type": "passive",
      "score": 8,
      "recipient_id": "NnE0US9DZElTS25NNEU1QTcxL3BLOEVGcHNLV3FaWnJKeXNFd2svVGtIcz0=",
      "property_ids": [3, 8, 9, 13],
      "metatags": {
        "thank_you_note_all": "Thanks for your feedback about metatags!",
        "survey_question": "how do you like our product %[question subject]?",
        "request_for_comment_all": "Tell us a bit more about why you chose %[score] for metatags",
        "question_subject": "metatags"
      },
      "labels": ["Voucher"],
      "name": "Maxine Jacobs",
      "inserted_at": "2017-01-26T12:31:46.736219Z",
      "email": "test_1@test.com",
      "comment": "Hi Team, having problems with the voucher code…can you get back to me"
    },
    {
      "id": "REEvd2RzZzlOMUZFWnR1RFBGWjlpNEphZWE5Y1pteG9LTU5wQjN3dTNlcz0=",
      "score_type": "promoter",
      "score": 9,
      "recipient_id": "R1FEaUNTSUxhMjBsUHFiUWl2Z0RIV3BHeWZpT0l6eE5oaVVJMVNnT3NXdz0=",
      "property_ids": [4, 7, 12, 14],
      "metatags": {
        "thank_you_note_all": "Thanks for your feedback about metatags!",
        "survey_question": "how do you like our product %[question subject]?",
        "request_for_comment_all": "Tell us a bit more about why you chose %[score] for metatags",
        "question_subject": "metatags"
      },
      "labels": [],
      "name": "John Finley",
      "inserted_at": "2017-01-26T08:55:46.740574Z",
      "email": "test_2@test.com",
      "comment": null
    },
    {
      "id": "Q2VEL1dQR3hzRUZxckZBOWNhQ3hGM0JMZzhYSWhSaTc3dnEwbGNPbUEvZz0=",
      "score_type": "detractor",
      "score": 5,
      "recipient_id": "V1Npazk1a09oNDlKcXVYb1NpTUJUSlhMczYrZVM3ZTFLcHV1YmNUZmFOWT0=",
      "property_ids": [2, 6],
      "metatags": {
        "thank_you_note_all": "Thanks for your feedback about metatags!",
        "survey_question": "how do you like our product %[question subject]?",
        "request_for_comment_all": "Tell us a bit more about why you chose %[score] for metatags",
        "question_subject": "metatags"
      },
      "labels": ["Product"],
      "name": "Irene Adams",
      "inserted_at": "2017-01-26T05:19:46.744313Z",
      "email": "test_3@test.com",
      "comment": "Site is too slow, and I can't order by phone. But the product turned up really quickly"
    },
    {
      "id": "TVZDa1Z2K0JJaWhwU3ZodzY3YjRDV01SWWhYQ0MwWHpCS1FzVktnaWprOD0=",
      "score_type": "promoter",
      "score": 9,
      "recipient_id": "TksyMGxsd215dFpON2s0S2NVbk50M0hHT3NqeDlscjNyTnAvaExEL3JYND0=",
      "property_ids": [2, 6],
      "metatags": {
        "thank_you_note_all": "Thanks for your feedback about metatags!",
        "survey_question": "how do you like our product %[question subject]?",
        "request_for_comment_all": "Tell us a bit more about why you chose %[score] for metatags",
        "question_subject": "metatags"
      },
      "labels": [],
      "name": "Denise Moore",
      "inserted_at": "2017-01-26T01:43:46.74778Z",
      "email": "test_4@test.com",
      "comment": null
    }
  ]
}
{
  "error": {
    "status": 400,
    "code": "INVALID_REQUEST",
    "links": {
      "documentation": "https://docs.zenloop.com/v1.0/reference#get-answers"
    },
    "title": "Invalid request body.",
    "details": [
      {
        "detail": "Value \"\" is not allowed in enum.",
        "pointer": "/answer_type"
      },
      {
        "detail": "Value \"\" is not allowed in enum.",
        "pointer": "/date_shortcut"
      },
      {
        "detail": "Value \"\" is not allowed in enum.",
        "pointer": "/order_by"
      },
      {
        "detail": "Value \"\" is not allowed in enum.",
        "pointer": "/order_type"
      }
    ]
  }
}
{
  "error": {
    "status": 401,
    "code": "UNAUTHORIZED",
    "title": "Invalid or expired token."
  }
}
{
  "error": {
    "status": 404,
    "code": "NOT_FOUND",
    "title": "Survey not found."
  }
}
{
  "error": {
    "status": 429,
    "code": "TOO_MANY_REQUESTS",
    "title": "Rate limit exceeded."
  }
}

Path Params

survey_id
string
required

Unique ID of a survey

Query Params

date_shortcut
string

Date range for which we want to fetch answers. Allowed values: today, yesterday, last_week, last_month, last_7_days, last_30_days, all_time

comment_content
string

Comment content filter for the answers.

order_by
string

Result sort. Allowed values: rating, inserted_at

order_type
string

Sort answer ascending or descending. Allowed values: asc, desc

with_comments
boolean

Filters answer with comments only. Allowed values: true, false

answer_type
string

Filters particular answers type only. Allowed values: detractors, passives, promoters

page
int32

Number of the page of the results you would like to get.

properties
object

Filter by properties. The key should be the name of the property, the value should be a list of comma-separated property ids

 

Headers

Authorization
string
required
Content-Type
string
required
 
{
  "date_shortcut": "all_time",
  "comment_content": "great",
  "order_by": "rating",
  "order_type": "asc",
  "with_comments": true,
  "answer_type": "promoters",
  "properties" : {"color" : "RkJrQllReklDTmk0cmRtTUVMUGw2SWJKUStHTk1lZG5WMFppSUIzdmxvOD0=,czhlUW5yZXdNR0t5eW16T3A5OWx3RXJnV2FNaDNEc0J1K2FMdGFUSVRwMD0=",
                 "country" : "Yzg4TDJwVnNtNDM2Nm1Ca2hpdjMrUmdBODN4Z1Blb053cFB3eFo4MmR4dz0="},
  "page": 1
}

Response attributes

Attribute Type Description
survey object Survey information data.
survey.title string Survey title.
survey.status string Survey status. One of: draft, active
survey.response_rate string Survey response rate (all time) - only for "our email" channel.
survey.public_hash_id string Survey public hash id used to identify survey.
survey.promoters object Summary data about promoters from survey answers.
survey.promoters.percentage number Percentage of answers that were promoters.
survey.promoters.delta number Promoters delta - describing the +/- change since the previous period.
survey.passives object Summary data about passives from survey answers.
survey.passives.percentage number Percentage of answers that were passives.
survey.passives.delta number Passives delta - describing the +/- change since the previous period.
survey.number_of_responses number Number of answers.
survey.nps object Summary data about NPS from survey answers.
survey.nps.percentage number The NPS score.
survey.nps.delta number NPS delta - describing the +/- change since the previous period.
survey.inserted_at date Survey creation date.
survey.detractors object Summary data about detractors from survey answers.
survey.detractors.percentage number Percentage of answers that were detractors.
survey.detractors.delta number Detractors delta - describing the +/- change since the previous period.
properties array List of properties for the survey answers.
properties.name string Property name.
properties.value string Property value.
properties.id number Property Id.
meta object Result metadata.
meta.total number Number of answers.
meta.survey_has_answers boolean Flag if survey has answers.
meta.per_page number Number of answers per page.
meta.page number Current results page.
answers array Survey answer.
answers.id string Answer identifier.
answers.score_type string Score type for the answer.
answers.score number Actual score for the answer.
answers.name string Name of survey recipient who submitted the answer.
answers.recipient_id string ID of a recipient who submitted the answer.
answers.property_ids array Array of property identifiers for the answer.
answers.metatags object List of metatags for the answer.
answers.labels array List of labels for the answer.
answers.inserted_at date Date when an answer has been submitted.
answers.email string Email of survey recipient who submitted the answer.
answers.comment string Answer comment of survey recipient who submitted the answer.
Suggest Edits

Get List of Surveys

This endpoint is used for getting basic data for all surveys from user organization.

 

Header Auth

 Authentication is required for this endpoint.
gethttps://api.zenloop.com/v1/surveys
curl --request GET \
  --url https://api.zenloop.com/v1/surveys \
  --header 'authorization: Bearer <token>' \
  --header 'content-type: application/json'
var request = require("request");

var options = { method: 'GET',
  url: 'https://api.zenloop.com/v1/surveys',
  headers: 
   { 'content-type': 'application/json',
     authorization: 'Bearer <token>' } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
require 'uri'
require 'net/http'

url = URI("https://api.zenloop.com/v1/surveys")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["authorization"] = 'Bearer <token>'
request["content-type"] = 'application/json'

response = http.request(request)
puts response.read_body
var data = JSON.stringify(false);

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://api.zenloop.com/v1/surveys");
xhr.setRequestHeader("authorization", "Bearer <token>");
xhr.setRequestHeader("content-type", "application/json");

xhr.send(data);
import requests

url = "https://api.zenloop.com/v1/surveys"

headers = {
    'authorization': "Bearer <token>",
    'content-type': "application/json"
    }

response = requests.request("GET", url, headers=headers)

print(response.text)
A binary file was returned

You couldn't be authenticated

{
  "surveys": [
    {
      "title": "Sample Test Survey",
      "status": "active",
      "public_hash_id": "RXpqTHZLTVNYU29nQnNzQ3V1VVgveEdmNTJTK2VheXNtc1lrN2VjOXdGZz0=",
      "inserted_at": "2016-10-13T13:02:21Z"
    }
  ],
  "meta": {
    "total": 1,
    "per_page": 12,
    "page": 1
  }
}
{
  "status": 400,
  "title": "Invalid request body.",
  "links": {
    "documentation": "https://docs.zenloop.com/v1.0/reference#get-list-of-surveys"
  },
  "code": "INVALID_REQUEST",
  "details": [{
    "detail": "Expected the value to be >= 1",
    "pointer": "/page"
  }]
}
{
  "error": {
    "status": 401,
    "code": "UNAUTHORIZED",
    "title": "Invalid or expired token."
  }
}
{
  "error": {
    "status": 429,
    "code": "TOO_MANY_REQUESTS",
    "title": "Rate limit exceeded."
  }
}

Query Params

page
int32

Number of the page of the results you would like to get.

Headers

Authorization
string
required
Content-Type
string
required
 
{
  "page": 1
}

Response attributes

Attribute Type Description
surveys array Survey information data.
surveys.title string Survey title.
surveys.status string Survey status. One of: draft, active
surveys.public_hash_id string Survey public hash id used to identify survey.
surveys.inserted_at date Survey creation date.
meta object Result metadata.
meta.total number Number of answers.
meta.per_page number Number of answers per page.
meta.page number Current results page.
Suggest Edits

Get Summary of Survey

This endpoint is used for fetching basic survey data and NPS scores.

 

Header Auth

 Authentication is required for this endpoint.
gethttps://api.zenloop.com/v1/surveys/survey_id
curl --request GET \
  --url https://api.zenloop.com/v1/surveys/survey_id \
  --header 'authorization: Bearer <token>' \
  --header 'content-type: application/json'
var request = require("request");

var options = { method: 'GET',
  url: 'https://api.zenloop.com/v1/surveys/survey_id',
  headers: 
   { 'content-type': 'application/json',
     authorization: 'Bearer <token>' } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
require 'uri'
require 'net/http'

url = URI("https://api.zenloop.com/v1/surveys/survey_id")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["authorization"] = 'Bearer <token>'
request["content-type"] = 'application/json'

response = http.request(request)
puts response.read_body
var data = JSON.stringify(false);

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://api.zenloop.com/v1/surveys/survey_id");
xhr.setRequestHeader("authorization", "Bearer <token>");
xhr.setRequestHeader("content-type", "application/json");

xhr.send(data);
import requests

url = "https://api.zenloop.com/v1/surveys/survey_id"

headers = {
    'authorization': "Bearer <token>",
    'content-type': "application/json"
    }

response = requests.request("GET", url, headers=headers)

print(response.text)
A binary file was returned

You couldn't be authenticated

{
  "survey":
    "title": "Sample Test Survey",
    "status": "active",
    "response_rate": "N/A",
    "public_hash_id": "RXpqTHZLTVNYU29nQnNzQ3V1VVgveEdmNTJTK2VheXNtc1lrN2VjOXdGZz0=",
    "promoters": {
      "percentage": 58.25,
      "delta": 0
    },
    "passives": {
      "percentage": 30.25,
      "delta": 0
    },
    "number_of_responses": 3,
    "nps": {
      "percentage": 46.75,
      "delta": 0
    },
    "inserted_at": "2016-10-13T13:02:21Z",
    "detractors": {
      "percentage": 11.5,
      "delta": 0
    }
  }
}
{
  "status": 400,
  "title": "Invalid request body.",
  "links": {
    "documentation": "https://docs.zenloop.com/v1.0/reference#get-summary-of-survey"
  },
  "code": "INVALID_REQUEST",
  "details": [{
    "detail": "Value \"invalid\" is not allowed in enum.",
    "pointer": "/date_shortcut"
  }]
}
{
  "error": {
    "status": 401,
    "code": "UNAUTHORIZED",
    "title": "Invalid or expired token."
  }
}
{
  "error": {
    "status": 404,
    "code": "NOT_FOUND",
    "title": "Survey not found."
  }
}
{
  "error": {
    "status": 429,
    "code": "TOO_MANY_REQUESTS",
    "title": "Rate limit exceeded."
  }
}

Path Params

survey_id
string
required

Unique ID of a survey

Query Params

date_shortcut
string

Date range for which we want to fetch answers. Allowed values: today, yesterday, last_week, last_month, last_7_days, last_30_days, all_time

Headers

Authorization
string
required
Content-Type
string
required
 
{
  "date_shortcut": "all_time"
}

Response attributes

Attribute Type Description
survey object Survey information data.
survey.title string Survey title.
survey.status string Survey status. One of: draft, active
survey.response_rate string Survey response rate.
survey.public_hash_id string Survey public hash id used to identify survey.
survey.promoters object Summary data about promoters from survey answers.
survey.promoters.percentage number Percentage of answers that were promoters.
survey.promoters.delta number Promoters delta - describing the +/- change for the similar period we measure against.
survey.passives object Summary data about passives from survey answers.
survey.passives.percentage number Percentage of answers that were passives.
survey.passives.delta number Passives delta - describing the +/- change for the similar period we measure against.
survey.number_of_responses number Number of answers.
survey.nps object Summary data about NPS from survey answers.
survey.nps.percentage number The NPS score.
survey.nps.delta number NPS delta - describing the +/- change for the similar period we measure against.
survey.inserted_at date Survey creation date.
survey.detractors object Summary data about detractors from survey answers.
survey.detractors.percentage number Percentage of answers that were detractors.
survey.detractors.delta number Detractors delta - describing the +/- change for the similar period we measure against.
Suggest Edits

Get List of Properties

This endpoint is used for fetching properties from answers belonging to a given survey

 

Header Auth

 Authentication is required for this endpoint.
gethttps://api.zenloop.com/v1/surveys/survey_id/properties
curl --request GET \
  --url https://api.zenloop.com/v1/surveys/survey_id/properties \
  --header 'authorization: Bearer <token>' \
  --header 'content-type: application/json'
var request = require("request");

var options = { method: 'GET',
  url: 'https://api.zenloop.com/v1/surveys/survey_id/properties',
  headers: 
   { 'content-type': 'application/json',
     authorization: 'Bearer <token>' } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
require 'uri'
require 'net/http'

url = URI("https://api.zenloop.com/v1/surveys/survey_id/properties")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["authorization"] = 'Bearer <token>'
request["content-type"] = 'application/json'

response = http.request(request)
puts response.read_body
var data = JSON.stringify(false);

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://api.zenloop.com/v1/surveys/survey_id/properties");
xhr.setRequestHeader("authorization", "Bearer <token>");
xhr.setRequestHeader("content-type", "application/json");

xhr.send(data);
import requests

url = "https://api.zenloop.com/v1/surveys/survey_id/properties"

headers = {
    'authorization': "Bearer <token>",
    'content-type': "application/json"
    }

response = requests.request("GET", url, headers=headers)

print(response.text)
A binary file was returned

You couldn't be authenticated

{
    "properties": [
        {
            "value": "blue",
            "name": "color",
            "id": "RkJrQllReklDTmk0cmRtTUVMUGw2SWJKUStHTk1lZG5WMFppSUIzdmxvOD0="
        },
        {
            "value": "red",
            "name": "color",
            "id": "czhlUW5yZXdNR0t5eW16T3A5OWx3RXJnV2FNaDNEc0J1K2FMdGFUSVRwMD0="
        },
        {
            "value": "spain",
            "name": "country",
            "id": "dmdIREl6S2t5dHg4aWRGQ2RJN1FFSDJ3ODFzRjY1ck1lYk9xdnIxMjF0ST0="
        }
    ],
    "meta": {
        "total": 3,
        "per_page": 50,
        "page": 1
    }
}
{
    "error": {
        "title": "Invalid request body.",
        "status": 400,
        "links": {
            "documentation": "https://docs.zenloop.com/v1.0/reference#get-list-of-properties"
        },
        "details": [
            {
                "pointer": "/page",
                "detail": "Expected the value to be >= 1"
            }
        ],
        "code": "INVALID_REQUEST"
    }
}
{
    "error": {
        "title": "Invalid or expired token.",
        "status": 401,
        "code": "UNAUTHORIZED"
    }
}
{
    "error": {
        "title": "Survey not found.",
        "status": 404,
        "code": "NOT_FOUND"
    }
}

Path Params

survey_id
string
required

Unique ID of a survey

Query Params

name
string

Filter properties with name equal to this parameter (case insensitive)

search
string

Filter properties with value starting with the parameter (case insensitive)

page
int32

Number of the page of the results you would like to get.

Headers

Authorization
string
required
Content-Type
string
required
 
{
  "name": "color",
  "search": "blu",
  "page": 1
}

Response attributes

Attribute Type Description
properties array List of properties for the survey answers.
properties.name string Property name.
properties.value string Property value.
properties.id number Property Id.
meta object Result metadata.
meta.total number Number of answers.
meta.per_page number Number of answers per page.
meta.page number Current results page.