Suggest Edits

Introduction

 

Welcome to Version 2 of the Promoter API! You can use our API to access endpoints, which can get information on various contacts, feedback, and campaign metrics in our database.

We have a robust API to provide tons of options for all needs, but the most popular use is triggering to send surveys, found in the Contacts section below.

Enhancements for V2

  • Valid JSON now accepted. Before, data passed in needed to be 'strings'. Data can now be formatted to be valid JSON.

Contacts

  • "Survey a contact" has survey-level attributes. Your attributes on the contact object can be continually updated, but now you can capture attributes at the time the survey was sent. Also a new endpoint with enhanced performance.

Feedback

  • "Get feedback" call will return survey-level attributes. If you passed in survey-level attributes in your survey call, you can retrieve that info in the "get feedback" call on the survey object.

  • Follow-up actions available. Reply and Forward using the API.

  • Tagging feedback is now available.

  • Update the status of a feedback to be either OPEN or CLOSED.

Common Replies

  • Now you can get/create/delete common replies to be used within the app.

Webhooks

We've added more webhooks!

  • feedback.status_changed
  • feedback.tags_added_or_changed
  • tag.merged
  • tag.removed

API Rate Limiting

Based on your plan, you will be allowed an API request rate of X requests per minute. Your limit can be found by visiting the "API" section of your account.

When the requests per minute exceed the allotment, you will receive the following:

A response status code of: 429 (Too many Requests)
A response body of:

{ "detail": "Request was throttled. Expected available in 42.0 seconds."}

A response header to inform of the client when in time you can retry the call:

Suggest Edits

Authentication

 

Promoter uses API keys to allow access to the API. You can register for a Promoter Account and access the API key in your main account settings under 'API'. Promoter expects for the API key to be included in all API requests to the server in a header that looks like the following: Authorization: Token YOUR_API_KEY. The key should be prefixed by the string literal "Token", with whitespace separating the two strings.

With curl, you can pass the correct header with each request curl "https://app.promoter.io/api".

Suggest Edits

Error Codes

 
Error Code
Message
Meaning

403

Forbidden

The resource requested is hidden for administrators only

404

Not Found

The specified resource could not be found

405

Method Not Allowed

You tried to access a resource with an invalid method

406

Not Acceptable

You requested a format that isn’t json

410

Gone

The resource requested has been removed from our servers

429

Too Many Requests

You’re requesting too much! Slow down!

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.

Suggest Edits

Data Policy

 

Attribute Names and Values

Any data uploaded can only contain alphanumeric characters:

letters “a - z” / ”A - Z

“plan” , “ID”, “Company”

numbers 0 - 9

009, 49, 1234

underscores ( _ )

“region_024”, “company_name"

spaces ( )

“Plan Name”, “company name”

Characters NOT accepted:

dollar signs ($)

“MRR$”, “$plan”

periods (.)

“MRR.1”, “plan.name”

percentage signs (%)

“%revenue”, “% of data”

Ampersand (&)

“Address & Phone”

Dates as Attribute Values

Date/times must be in the “yyyy-mm-ddThh:mm:ss” format (“ISO 8601” format) to be recognized as dates.

✔ Correct:

2017-09-23
2017-09-23T15:25
2017-09-23 15:25
2017-09-23T15:25:45
2017-09-23T15:25:45Z

X Incorrect:

9-23-17
9/23/17
23/09/17
2017-9-23
09-23-2017

Suggest Edits

Survey a contact

 
posthttps://app.promoter.io/api/v2/survey/
curl --include \
     --request POST \
     --header "Content-Type: application/json" \
     --header "Authorization: Token YOUR_API_KEY" \
     --data-binary "{
    \"campaign_id\":99, 
    \"contact\":{
        \"email\":\"kate@mac.com\",
        \"first_name\":\"Kate\",
        \"last_name\":\"Bell\",
        \"attributes\":{
            \"plan\":\"gold\",
            \"signed_up\":\"2014-12-12T10:00:00Z\"
        }
    },
    \"attributes\":{
        \"OrderId\":123456789
    }
}" \
'https://app.promoter.io/api/v2/survey/'
var request = new XMLHttpRequest();

request.open('POST', 'https://app.promoter.io/api/v2/survey/
');

request.setRequestHeader('Content-Type', 'application/json');
request.setRequestHeader('Authorization', 'Token YOUR_API_KEY');

request.onreadystatechange = function () {
  if (this.readyState === 4) {
    console.log('Status:', this.status);
    console.log('Headers:', this.getAllResponseHeaders());
    console.log('Body:', this.responseText);
  }
};

var body = {
    'campaign_id':99,
    'contact':{
        'email':'kate@mac.com',
        'first_name':'Kate',
        'last_name':'Bell',
        'attributes':{
            'plan': 'gold',
            'signed_up': '2014-12-12T10:00:00Z'
        }
    },
    'attributes':{
        'OrderId':123456789
    }
};

request.send(JSON.stringify(body));
from urllib2 import Request, urlopen

values = """
  {
    "campaign_id":99,
    "contact":{
        "email":"kate@mac.com",
        "first_name":"Kate",
        "last_name":"Bell",
        "attributes":{
            "plan": "gold",
            "signed_up": "2014-12-12T10:00:00Z"
        }
    },
    "attributes":{
        "OrderId":123456789
    }
  }
"""

headers = {
  'Content-Type': 'application/json',
  'Authorization': 'Token YOUR_API_KEY'
}
request = Request('https://app.promoter.io/api/v2/survey/
', data=values, headers=headers)

response_body = urlopen(request).read()
print response_body
require 'rubygems' if RUBY_VERSION < '1.9'
require 'rest_client'

values = '{
		"campaign_id":99,
    "contact":{
        "email":"kate@mac.com",
        "first_name":"Kate",
        "last_name":"Bell",
				"attributes":{
            "plan": "gold",
            "signed_up": "2014-12-12T10:00:00Z"
        }
    },
    "attributes":{
        "OrderId":123456789
    }
}'

headers = {
  :content_type => 'application/json',
  :authorization => 'Token YOUR_API_KEY'
}

response = RestClient.post 'https://app.promoter.io/api/v2/survey/
', values, headers
puts response
// Maven : Add these dependecies to your pom.xml (java6+)
// <dependency>
//     <groupId>org.glassfish.jersey.core</groupId>
//     <artifactId>jersey-client</artifactId>
//     <version>2.8</version>
// </dependency>
// <dependency>
//     <groupId>org.glassfish.jersey.media</groupId>
//     <artifactId>jersey-media-json-jackson</artifactId>
//     <version>2.8</version>
// </dependency>

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;

Client client = ClientBuilder.newClient();
Entity payload = Entity.json("{      
    \"campaign_id\":99,
    \"contact\":{
        \"email\":\"kate@mac.com\",
        \"first_name\":\"Kate\",
        \"last_name\":\"Bell\",
        \"attributes\":{
            \"plan\":\"gold\",
            \"signed_up\":\"2014-12-12T10:00:00Z\"
        }                     
    },
    \"attributes\":{
        \"OrderId\":123456789
    }}");
Response response = client.target("https://app.promoter.io/api/v2/survey/
")
  .request(MediaType.APPLICATION_JSON_TYPE)
  .header("Authorization", "Token YOUR_API_KEY")
  .post(payload);

System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));
//Common testing requirement. If you are consuming an API in a sandbox/test region, uncomment this line of code ONLY for non production uses.
//System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

//Be sure to run "Install-Package Microsoft.Net.Http" from your nuget command line.
using System;
using System.Net.Http;

var baseAddress = new Uri("https://app.promoter.io/api/v2/survey/");

using (var httpClient = new HttpClient{ BaseAddress = baseAddress })
{

  
  httpClient.DefaultRequestHeaders.TryAddWithoutValidation("authorization", "Token YOUR_API_KEY");
  
    using (var content = new StringContent("{ 
    \"campaign_id\":99,
    \"contact\":{
        \"email\":\"kate@mac.com\",
        \"first_name\":\"Kate\",
        \"last_name\":\"Bell\",
        \"attributes\":{
            \"plan\":\"gold\",
            \"signed_up\":\"2014-12-12T10:00:00Z\"
        }
    },
    \"attributes\":{
        \"OrderId\":123456789
    }}", System.Text.Encoding.Default, "application/json"))
    {
      using (var response = await httpClient.PostAsync("undefined", content))
      {
        string responseData = await response.Content.ReadAsStringAsync();
      }
  }
}
<?php
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://app.promoter.io/api/v2/survey/
");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);

curl_setopt($ch, CURLOPT_POST, TRUE);

curl_setopt($ch, CURLOPT_POSTFIELDS, "{
    \"campaign_id\":99,
    \"contact\":{
        \"email\":\"kate@mac.com\",
        \"first_name\":\"Kate\",
        \"last_name\":\"Bell\",
        \"attributes\":{
            \"plan\":\"gold\",
            \"signed_up\":\"2014-12-12T10:00:00Z\"
        }
    },
    \"attributes\":{
        \"OrderId\":123456789
    }");

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
  "Content-Type: application/json",
  "Authorization: Token YOUR_API_KEY"
));

$response = curl_exec($ch);
curl_close($ch);

var_dump($response);
A binary file was returned

You couldn't be authenticated

{
    "contact": {
        "email": "kate@mac.com",
      	"first_name": "Kate",
      	"last_name": "Mac",
         "attributes":{
            "plan": "gold",
            "signed_up": "2014-12-12T10:00:00Z"
        }
    },
    "campaign_id": 99,
    "status": "SENT",
    "attributes": {
    	"OrderId":"123456789"
    }
}
{"contact":["Contact has unsubscribed."]}

OR

{"contact":{"email":["Enter a valid email address."]}}

OR

{"campaign":["Organization does not have permission to access campaign."]}

OR

{"campaign":["Campaign requires a contact list to be associated."]}

Body Params

campaign_id
string
required

Id of the campaign that will send the survey

email
string
required

Contact's email

first_name
string

Contact's first name

last_name
string

Contact's last name

contact -> attributes
mixed type

A dictionary of key value pairs of custom attributes that will be associated with the contact.

attributes
mixed type

A dictionary of key value pairs of custom attributes that will be associated with the survey.

Headers

Authorization
string
required

Your account's API key ("Token API_KEY")

Content-Type
string
required

Must be "application/json"

 

The minimum requirements for surveying a contact are the contact’s email and the campaign id to survey them from.

  1. Before sending surveys via the API, a campaign must be first created manually in the app.
  2. After creating the campaign, visit the API settings in the "Integrations" section.
  3. Click to '+ Add Integration' and choose the campaign.
  4. Choose the delivery settings for surveys being triggered with the API for that campaign.

When surveying contacts, there are not limits to how many attributes can be passed in. These can be useful when filtering NPS analytics on the campaign's dashboard.

  • Depending on your Survey Throttle setting, your contact may not be surveyed if they have been recently surveyed. (Survey Throttle setting can be found in your account settings.)

24 Hour Survey Throttle

Our system has a 24 hour throttle built in so any contact cannot be surveyed more than once in a 24 hour period. Due to this, you may need to use aliases of your email while testing.

Ex: joe+1@mac.com, joe+2@mac.com...

If you would like this temporarily disabled while testing, please write in to support@promoter.io.

Suggest Edits

Update a Contact

 
posthttps://app.promoter.io/api/v2/contacts/
curl --include \
     --request POST \
     --header "Authorization: Token YOUR_API_TOKEN" \
     --header "Content-Type: application/json" \
     --data-binary "{
    \"email\":\"kate@mac.com\",
    \"first_name\":\"Kate\",
    \"last_name\":\"Bell\",
    \"unsubscribed\":false,
    \"attributes\":{
        \"Source\":\"Support Ticket\", 
        \"plan\":\"bronze\", 
        \"Reference\":\"123456\"
    }
}" \
'https://app.promoter.io/api/v2/contacts/'
var request = new XMLHttpRequest();

request.open('POST', 'https://app.promoter.io/api/v2/contacts/
');

request.setRequestHeader('Authorization', 'Token YOUR_API_TOKEN');
request.setRequestHeader('Content-Type', 'application/json');

request.onreadystatechange = function () {
  if (this.readyState === 4) {
    console.log('Status:', this.status);
    console.log('Headers:', this.getAllResponseHeaders());
    console.log('Body:', this.responseText);
  }
};

var body = {
  'contact_list': [
    4865
  ],
  'email': 'kate@mac.com',
  'first_name': 'Kate',
  'last_name': 'Bell',
  'unsubscribed': 'false',
  'attributes': {
    'Source': 'Support Ticket',
    'plan': 'bronze',
    'Reference': '123456'
  }
};

request.send(JSON.stringify(body));
from urllib2 import Request, urlopen

values = """
  {
    "contact_list": [
      4865
    ],
    "email": "kate@mac.com",
    "first_name": "Kate",
    "last_name": "Bell",
    "unsubscribed": "false",
    "attributes": {
      "Source": "Support Ticket",
      "plan": "bronze",
      "Reference": "123456"
    }
  }
"""

headers = {
  'Authorization': 'Token YOUR_API_TOKEN',
  'Content-Type': 'application/json'
}
request = Request('https://app.promoter.io/api/v2/contacts/
', data=values, headers=headers)

response_body = urlopen(request).read()
print response_body
require 'rubygems' if RUBY_VERSION < '1.9'
require 'rest_client'

values = '{
  "contact_list": [
    4865
  ],
  "email": "kate@mac.com",
  "first_name": "Kate",
  "last_name": "Bell",
  "unsubscribed": "false",
  "attributes": {
    "Source": "Support Ticket",
    "plan": "bronze",
    "Reference": "123456"
  }
}'

headers = {
  :authorization => 'Token YOUR_API_TOKEN',
  :content_type => 'application/json'
}

response = RestClient.post 'https://app.promoter.io/api/v2/contacts/
', values, headers
puts response
// Maven : Add these dependecies to your pom.xml (java6+)
// <dependency>
//     <groupId>org.glassfish.jersey.core</groupId>
//     <artifactId>jersey-client</artifactId>
//     <version>2.8</version>
// </dependency>
// <dependency>
//     <groupId>org.glassfish.jersey.media</groupId>
//     <artifactId>jersey-media-json-jackson</artifactId>
//     <version>2.8</version>
// </dependency>

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;

Client client = ClientBuilder.newClient();
Entity payload = Entity.json("{  'contact_list': [    4865  ],  'email': 'kate@mac.com',  'first_name': 'Kate',  'last_name': 'Bell',  'unsubscribed': 'false',  'attributes': {    'Source': 'Support Ticket',    'plan': 'bronze',    'Reference': '123456'  }}");
Response response = client.target("https://app.promoter.io/api/v2/contacts/
")
  .request(MediaType.APPLICATION_JSON_TYPE)
  .header("Authorization", "Token YOUR_API_TOKEN")
  .post(payload);

System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));
//Common testing requirement. If you are consuming an API in a sandbox/test region, uncomment this line of code ONLY for non production uses.
//System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

//Be sure to run "Install-Package Microsoft.Net.Http" from your nuget command line.
using System;
using System.Net.Http;

var baseAddress = new Uri("https://app.promoter.io/api/");

using (var httpClient = new HttpClient{ BaseAddress = baseAddress })
{

  httpClient.DefaultRequestHeaders.TryAddWithoutValidation("authorization", "Token YOUR_API_TOKEN");
  
  
    using (var content = new StringContent("{  \"contact_list\": [    4865  ],  \"email\": \"kate@mac.com\",  \"first_name\": \"Kate\",  \"last_name\": \"Bell\",  \"unsubscribed\": \"false\",  \"attributes\": {    \"Source\": \"Support Ticket\",    \"plan\": \"bronze\",    \"Reference\": \"123456\"  }}", System.Text.Encoding.Default, "application/json"))
    {
      using (var response = await httpClient.PostAsync("undefined", content))
      {
        string responseData = await response.Content.ReadAsStringAsync();
      }
  }
}
<?php
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://app.promoter.io/api/v2/contacts/
");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);

curl_setopt($ch, CURLOPT_POST, TRUE);

curl_setopt($ch, CURLOPT_POSTFIELDS, "{
  \"contact_list\": [
    4865
  ],
  \"email\": \"kate@mac.com\",
  \"first_name\": \"Kate\",
  \"last_name\": \"Bell\",
  \"unsubscribed\": \"false\",
  \"attributes\": {
    \"Source\": \"Support Ticket\",
    \"plan\": \"bronze\",
    \"Reference\": \"123456\"
  }
}");

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
  "Authorization: Token YOUR_API_TOKEN",
  "Content-Type: application/json"
));

$response = curl_exec($ch);
curl_close($ch);

var_dump($response);
A binary file was returned

You couldn't be authenticated

 {
    "id": 744011,                           
    "email": "kate@mac.com",                
    "first_name": "Kate",                   
    "last_name": "Bell",                    
    "created_date": "2014-12-12T10:00:00Z", 
    "unsubscribed": false,                
    "attributes": {                         
        "Source": "Support Ticket",
        "Reference": "123456",
        "plan": "bronze"
        }
}

Body Params

email
string
required

Email of the contact

first_name
string

First name of the contact

last_name
string

Last name of the contact

attributes
mixed type

A dictionary of key value pairs of custom attributes that will be associated with the contact

Headers

Authorization
string
required

This is where you'll provide your API key, after inserting the word 'Token' and a space

Content-Type
string
required

Must be specified as "application/json"

 

This action only updates a contact's info and does not send them a survey.

You can add as many attributes as you’d like along with your contact. These can be useful when analyzing NPS data on the campaign dashboard and using the 'Filter Segments' option.

The parameter required when updating a contact is the contact’s email. A contact's email is stored as a primary key, and this is how our system identifies which contact to update. We keep a master record of every contact even if they were removed from a contact list. Running this call will update their master record and be reflected all throughout the app (all lists, campaigns, etc.).

When attribute data is passed in the "/survey/" call, this will also update your contact's data while triggering a survey.

Suggest Edits

Unsubscribe a contact

 
posthttps://app.promoter.io/api/v2/contacts/unsubscribe/
curl --include \
     --request POST \
     --header "Authorization: Token YOUR_API_KEY" \
     --header "Content-Type: application/json" \
     --data-binary "{
    \"emails\":[\"kate@mac.com\"]
}" \
'https://app.promoter.io/api/v2/contacts/unsubscribe/'
var request = new XMLHttpRequest();

request.open('POST', 'https://app.promoter.io/api/v2/contacts/unsubscribe/
');

request.setRequestHeader('Authorization', 'Token YOUR_API_KEY');
request.setRequestHeader('Content-Type', 'application/json');

request.onreadystatechange = function () {
  if (this.readyState === 4) {
    console.log('Status:', this.status);
    console.log('Headers:', this.getAllResponseHeaders());
    console.log('Body:', this.responseText);
  }
};

var body = {
  'emails': [
    'kate@mac.com'
  ]
};

request.send(JSON.stringify(body));
from urllib2 import Request, urlopen

values = """
  {
    "emails": [
      "kate@mac.com"
    ]
  }
"""

headers = {
  'Authorization': 'Token YOUR_API_KEY',
  'Content-Type': 'application/json'
}
request = Request('https://app.promoter.io/api/v2/contacts/unsubscribe/
', data=values, headers=headers)

response_body = urlopen(request).read()
print response_body
require 'rubygems' if RUBY_VERSION < '1.9'
require 'rest_client'

values = '{
  "emails": [
    "kate@mac.com"
  ]
}'

headers = {
  :authorization => 'Token YOUR_API_KEY',
  :content_type => 'application/json'
}

response = RestClient.post 'https://app.promoter.io/api/v2/contacts/unsubscribe/
', values, headers
puts response
// Maven : Add these dependecies to your pom.xml (java6+)
// <dependency>
//     <groupId>org.glassfish.jersey.core</groupId>
//     <artifactId>jersey-client</artifactId>
//     <version>2.8</version>
// </dependency>
// <dependency>
//     <groupId>org.glassfish.jersey.media</groupId>
//     <artifactId>jersey-media-json-jackson</artifactId>
//     <version>2.8</version>
// </dependency>

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;

Client client = ClientBuilder.newClient();
Entity payload = Entity.json("{  'emails': [    'kate@mac.com'  ]}");
Response response = client.target("https://app.promoter.io/apiv2//contacts/unsubscribe/
")
  .request(MediaType.APPLICATION_JSON_TYPE)
  .header("Authorization", "Token YOUR_API_KEY")
  .post(payload);

System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));
//Common testing requirement. If you are consuming an API in a sandbox/test region, uncomment this line of code ONLY for non production uses.
//System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

//Be sure to run "Install-Package Microsoft.Net.Http" from your nuget command line.
using System;
using System.Net.Http;

var baseAddress = new Uri("https://app.promoter.io/api/");

using (var httpClient = new HttpClient{ BaseAddress = baseAddress })
{

  httpClient.DefaultRequestHeaders.TryAddWithoutValidation("authorization", "Token YOUR_API_KEY");
  
  
    using (var content = new StringContent("{  \"emails\": [    \"kate@mac.com\"  ]}", System.Text.Encoding.Default, "application/json"))
    {
      using (var response = await httpClient.PostAsync("undefined", content))
      {
        string responseData = await response.Content.ReadAsStringAsync();
      }
  }
}
<?php
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://app.promoter.io/api/v2/contacts/unsubscribe/
");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);

curl_setopt($ch, CURLOPT_POST, TRUE);

curl_setopt($ch, CURLOPT_POSTFIELDS, "{
  \"emails\": [
    \"kate@mac.com\"
  ]
}");

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
  "Authorization: Token YOUR_API_KEY",
  "Content-Type: application/json"
));

$response = curl_exec($ch);
curl_close($ch);

var_dump($response);
A binary file was returned

You couldn't be authenticated

{"count":0,"next":null,"previous":null,"results":[]}

Body Params

emails
array of strings
required

Email(s) of the contact to unsubscribe.

Headers

Authorization
string
required

This is where you'll provide your API key, after inserting the word 'Token' and a space

Content-Type
string
required

Must be specified as "application/json"

 

Unsubscribing a contact will prevent the contact from being surveyed in the future. The unsubscribe action will also cancel all future pending surveys that were scheduled for that contact.

To re-subscribe a contact, use the 'update a contact' call and pass in 'unsubscribed : false'.

Suggest Edits

Get contact

 
gethttps://app.promoter.io/api/v2/contacts/
curl --include \
     --header "Authorization: Token YOUR_API_KEY" \
     --header "Content-Type: application/json" \
  'https://app.promoter.io/api/v2/contacts/'
var request = new XMLHttpRequest();

request.open('GET', 'https://app.promoter.io/api/v2/contacts/');

request.setRequestHeader('Authorization', 'Token YOUR_API_KEY');
request.setRequestHeader('Content-Type', 'application/json');

request.onreadystatechange = function () {
  if (this.readyState === 4) {
    console.log('Status:', this.status);
    console.log('Headers:', this.getAllResponseHeaders());
    console.log('Body:', this.responseText);
  }
};

request.send();
from urllib2 import Request, urlopen

headers = {
  'Authorization': 'Token YOUR_API_KEY',
  'Content-Type': 'application/json'
}
request = Request('https://app.promoter.io/api/v2/contacts/', headers=headers)

response_body = urlopen(request).read()
print response_body
require 'rubygems' if RUBY_VERSION < '1.9'
require 'rest_client'

headers = {
  :authorization => 'Token YOUR_API_KEY',
  :content_type => 'application/json'
}

response = RestClient.get 'https://app.promoter.io/api/v2/contacts/', headers
puts response
// Maven : Add these dependecies to your pom.xml (java6+)
// <dependency>
//     <groupId>org.glassfish.jersey.core</groupId>
//     <artifactId>jersey-client</artifactId>
//     <version>2.8</version>
// </dependency>
// <dependency>
//     <groupId>org.glassfish.jersey.media</groupId>
//     <artifactId>jersey-media-json-jackson</artifactId>
//     <version>2.8</version>
// </dependency>

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;

Client client = ClientBuilder.newClient();
Response response = client.target("https://app.promoter.io/api/v2/contacts/")
  .request(MediaType.APPLICATION_JSON_TYPE)
  .header("Authorization", "Token YOUR_API_KEY")
  .get();

System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));
//Common testing requirement. If you are consuming an API in a sandbox/test region, uncomment this line of code ONLY for non production uses.
//System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

//Be sure to run "Install-Package Microsoft.Net.Http" from your nuget command line.
using System;
using System.Net.Http;

var baseAddress = new Uri("https://app.promoter.io/api/");

using (var httpClient = new HttpClient{ BaseAddress = baseAddress })
{

  httpClient.DefaultRequestHeaders.TryAddWithoutValidation("authorization", "Token YOUR_API_KEY");
  
  
  using(var response = await httpClient.GetAsync("undefined"))
  {
 
        string responseData = await response.Content.ReadAsStringAsync();
  }
}
<?php
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://app.promoter.io/api/v2/contacts/");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
  "Authorization: Token YOUR_API_KEY",
  "Content-Type: application/json"
));

$response = curl_exec($ch);
curl_close($ch);

var_dump($response);
A binary file was returned

You couldn't be authenticated

 {
    "id": 744011,                           
    "email": "kate@mac.com",                
    "first_name": "Kate",                   
    "last_name": "Bell",                    
    "created_date": "2014-12-12T10:00:00Z", 
    "unsubscribed": "false",                
    "attributes": {                         
        "Source": "Support Ticket",
        "Reference": "123456",
        "plan": "bronze"
    }
}

Path Params

contact_id
int32
required

Query by the contact's id

Query Params

email
string

Query by a contact's email

contact_list__id
int32

Query by contact list id to grab all contacts within a list

Headers

Authorization
string
required

This is where you'll provide your API key, after inserting the word 'Token' and a space

Content-Type
string
required

Must be specified as "application/json"

 

This endpoint retrieves contacts in your organization.

Query by:

  • The contact's email to find a particular contact.
    /v2/contacts/?email=kate@mac.com

  • A contact_list_id to grab all contacts within a list.
    /v2/contacts/?contact_list__id=2099

When this call is made, it will return 100 results at a time and will require paginating through the results. To paginate, you would add a page parameter to the url. Ex: <api_call>/api/v2/contacts/?page=3

Suggest Edits

Get contact by id

 
gethttps://app.promoter.io/api/v2/contacts/contact_id/
curl --include \
     --header "Authorization: Token YOUR_API_KEY" \
     --header "Content-Type: application/json" \
  'https://app.promoter.io/api/v2/contacts/744011/'
var request = new XMLHttpRequest();

request.open('GET', 'https://app.promoter.io/api/v2/contacts/744011/
');

request.setRequestHeader('Authorization', 'Token YOUR_API_KEY');
request.setRequestHeader('Content-Type', 'application/json');

request.onreadystatechange = function () {
  if (this.readyState === 4) {
    console.log('Status:', this.status);
    console.log('Headers:', this.getAllResponseHeaders());
    console.log('Body:', this.responseText);
  }
};

request.send();
from urllib2 import Request, urlopen

headers = {
  'Authorization': 'Token YOUR_API_KEY',
  'Content-Type': 'application/json'
}
request = Request('https://app.promoter.io/api/v2/contacts/744011/
', headers=headers)

response_body = urlopen(request).read()
print response_body
require 'rubygems' if RUBY_VERSION < '1.9'
require 'rest_client'

headers = {
  :authorization => 'Token YOUR_API_KEY',
  :content_type => 'application/json'
}

response = RestClient.get 'https://app.promoter.io/api/v2/contacts/744011/
', headers
puts response
// Maven : Add these dependecies to your pom.xml (java6+)
// <dependency>
//     <groupId>org.glassfish.jersey.core</groupId>
//     <artifactId>jersey-client</artifactId>
//     <version>2.8</version>
// </dependency>
// <dependency>
//     <groupId>org.glassfish.jersey.media</groupId>
//     <artifactId>jersey-media-json-jackson</artifactId>
//     <version>2.8</version>
// </dependency>

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;

Client client = ClientBuilder.newClient();
Response response = client.target("https://app.promoter.io/api/v2/contacts/{contact_id}/
")
  .request(MediaType.APPLICATION_JSON_TYPE)
  .header("Authorization", "Token YOUR_API_KEY")
  .get();

System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));
//Common testing requirement. If you are consuming an API in a sandbox/test region, uncomment this line of code ONLY for non production uses.
//System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

//Be sure to run "Install-Package Microsoft.Net.Http" from your nuget command line.
using System;
using System.Net.Http;

var baseAddress = new Uri("https://app.promoter.io/api/");

using (var httpClient = new HttpClient{ BaseAddress = baseAddress })
{

  httpClient.DefaultRequestHeaders.TryAddWithoutValidation("authorization", "Token YOUR_API_KEY");
  
  
  using(var response = await httpClient.GetAsync("undefined"))
  {
 
        string responseData = await response.Content.ReadAsStringAsync();
  }
}
<?php
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://app.promoter.io/api/v2/contacts/{contact_id}/
");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
  "Authorization: Token YOUR_API_KEY",
  "Content-Type: application/json"
));

$response = curl_exec($ch);
curl_close($ch);

var_dump($response);
A binary file was returned

You couldn't be authenticated

{
        "id": 744011,                           
        "email": "kate@mac.com",                
        "first_name": "Kate",                   
        "last_name": "Bell",                    
        "created_date": "2014-12-12T10:00:00Z", 
        "unsubscribed": "false",                
        "attributes": {                         
            "Source": "Support Ticket",
            "Reference": "123456",
            "plan": "bronze"
        }
    }

Path Params

contact_id
int32
required

The contact's id you'd like to grab info for

Headers

Authorization
string
required

This is where you'll provide your API key, after inserting the word 'Token' and a space

Content-Type
string
required

Must be "application/json"

 

Retrieves a specific contact in your organization by providing the contact id.

Suggest Edits

Remove a contact

 
posthttps://app.promoter.io/api/contacts/remove/
curl --include \
     --request POST \
     --header "Content-Type: application/json" \
     --header "Authorization: Token YOUR_API_KEY" \
     --data-binary "{\"email\":\"kate@mac.com\"}" \
'https://app.promoter.io/api/contacts/remove/'
var request = new XMLHttpRequest();

request.open('POST', 'https://app.promoter.io/api/contacts/remove/
');

request.setRequestHeader('Content-Type', 'application/json');
request.setRequestHeader('Authorization', 'Token YOUR_API_KEY');

request.onreadystatechange = function () {
  if (this.readyState === 4) {
    console.log('Status:', this.status);
    console.log('Headers:', this.getAllResponseHeaders());
    console.log('Body:', this.responseText);
  }
};

var body = {
  'email': 'kate@mac.com'
};

request.send(JSON.stringify(body));
from urllib2 import Request, urlopen

values = """
  {
    "email": "kate@mac.com"
  }
"""

headers = {
  'Content-Type': 'application/json',
  'Authorization': 'Token YOUR_API_KEY'
}
request = Request('https://app.promoter.io/api/contacts/remove/
', data=values, headers=headers)

response_body = urlopen(request).read()
print response_body
require 'rubygems' if RUBY_VERSION < '1.9'
require 'rest_client'

values = '{
  "email": "kate@mac.com"
}'

headers = {
  :content_type => 'application/json',
  :authorization => 'Token YOUR_API_KEY'
}

response = RestClient.post 'https://app.promoter.io/api/contacts/remove/
', values, headers
puts response
// Maven : Add these dependecies to your pom.xml (java6+)
// <dependency>
//     <groupId>org.glassfish.jersey.core</groupId>
//     <artifactId>jersey-client</artifactId>
//     <version>2.8</version>
// </dependency>
// <dependency>
//     <groupId>org.glassfish.jersey.media</groupId>
//     <artifactId>jersey-media-json-jackson</artifactId>
//     <version>2.8</version>
// </dependency>

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;

Client client = ClientBuilder.newClient();
Entity payload = Entity.json("{  'email': 'kate@mac.com'}");
Response response = client.target("https://app.promoter.io/api/contacts/remove/
")
  .request(MediaType.APPLICATION_JSON_TYPE)
  .header("Authorization", "Token YOUR_API_KEY")
  .post(payload);

System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));
//Common testing requirement. If you are consuming an API in a sandbox/test region, uncomment this line of code ONLY for non production uses.
//System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

//Be sure to run "Install-Package Microsoft.Net.Http" from your nuget command line.
using System;
using System.Net.Http;

var baseAddress = new Uri("https://app.promoter.io/api/");

using (var httpClient = new HttpClient{ BaseAddress = baseAddress })
{

  
  httpClient.DefaultRequestHeaders.TryAddWithoutValidation("authorization", "Token YOUR_API_KEY");
  
    using (var content = new StringContent("{  \"email\": \"kate@mac.com\"}", System.Text.Encoding.Default, "application/json"))
    {
      using (var response = await httpClient.PostAsync("undefined", content))
      {
        string responseData = await response.Content.ReadAsStringAsync();
      }
  }
}
<?php
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://app.promoter.io/api/contacts/remove/
");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);

curl_setopt($ch, CURLOPT_POST, TRUE);

curl_setopt($ch, CURLOPT_POSTFIELDS, "{
  \"email\": \"kate@mac.com\"
}");

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
  "Content-Type: application/json",
  "Authorization: Token YOUR_API_KEY"
));

$response = curl_exec($ch);
curl_close($ch);

var_dump($response);
A binary file was returned

You couldn't be authenticated

{
  "count": 0,
  "next": null,
  "previous": null,
  "results": []
}

Body Params

email
string
required

The email of the contact to remove from the organization

Headers

Authorization
string
required

This is where you'll provide your API key, after inserting the word 'Token' and a space

Content-Type
string
required

Must be "application/json"

 

This endpoint removes a contact for an organization. This is a delete action and all of the contact’s data and history will be removed from the organization.

Suggest Edits

Get feedback

 
gethttps://app.promoter.io/api/v2/feedback/
curl --include \
     --header "Authorization: Token YOUR_API_KEY" \
     --header "Content-Type: application/json" \
  'https://app.promoter.io/api/v2/feedback/'
var request = new XMLHttpRequest();

request.open('GET', 'https://app.promoter.io/api/v2/feedback/');

request.setRequestHeader('Authorization', 'Token YOUR_API_KEY');
request.setRequestHeader('Content-Type', 'application/json');

request.onreadystatechange = function () {
  if (this.readyState === 4) {
    console.log('Status:', this.status);
    console.log('Headers:', this.getAllResponseHeaders());
    console.log('Body:', this.responseText);
  }
};

request.send();
from urllib2 import Request, urlopen

headers = {
  'Authorization': 'Token YOUR_API_KEY',
  'Content-Type': 'application/json'
}
request = Request('https://app.promoter.io/api/v2/feedback/', headers=headers)

response_body = urlopen(request).read()
print response_body
require 'rubygems' if RUBY_VERSION < '1.9'
require 'rest_client'

headers = {
  :authorization => 'Token YOUR_API_KEY',
  :content_type => 'application/json'
}

response = RestClient.get 'https://app.promoter.io/api/v2/feedback/', headers
puts response
// Maven : Add these dependecies to your pom.xml (java6+)
// <dependency>
//     <groupId>org.glassfish.jersey.core</groupId>
//     <artifactId>jersey-client</artifactId>
//     <version>2.8</version>
// </dependency>
// <dependency>
//     <groupId>org.glassfish.jersey.media</groupId>
//     <artifactId>jersey-media-json-jackson</artifactId>
//     <version>2.8</version>
// </dependency>

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;

Client client = ClientBuilder.newClient();
Response response = client.target("https://app.promoter.io/api/v2/feedback/
")
  .request(MediaType.APPLICATION_JSON_TYPE)
  .header("Authorization", "Token YOUR_API_KEY")
  .get();

System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));
//Common testing requirement. If you are consuming an API in a sandbox/test region, uncomment this line of code ONLY for non production uses.
//System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

//Be sure to run "Install-Package Microsoft.Net.Http" from your nuget command line.
using System;
using System.Net.Http;

var baseAddress = new Uri("https://app.promoter.io/api/v2/feedback/");

using (var httpClient = new HttpClient{ BaseAddress = baseAddress })
{

  httpClient.DefaultRequestHeaders.TryAddWithoutValidation("authorization", "Token YOUR_API_KEY");
  
  
  using(var response = await httpClient.GetAsync("undefined"))
  {
 
        string responseData = await response.Content.ReadAsStringAsync();
  }
}
<?php
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://app.promoter.io/api/v2/feedback/
");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
  "Authorization: Token YOUR_API_KEY",
  "Content-Type: application/json"
));

$response = curl_exec($ch);
curl_close($ch);

var_dump($response);
A binary file was returned

You couldn't be authenticated

{
  "id": 2387271,
  "href": "https://app.promoter.io/api/v2/feedback/12445/",
  "followup_href": "https://app.promoter.io/org/3925/campaign/23239/responses/all/response/12445/",
  "contact": {
    "attributes": {},
    "first_name": "Kate",
    "last_name": "Mac",
    "id": 23127796,
    "email": "kate@mac.com"
  },
  "campaign": {
    "id": 23239,
    "name": "My NPS Campaign",
    "launch_date": "2017-11-03T18:27:23Z",
    "status": "ACTIVE"
  },
  "score": 9,
  "created": "2017-11-27T17:51:41.900581Z",
  "score_changed": "2018-01-04T19:32:04.424509Z",
  "score_type": "promoter",
  "comment": "I love my new tablet! The price was great, but couldn't find anyone to help.",
  "comment_created": "2017-11-27T17:53:32.675321Z",
  "comment_modified": "2017-11-27T17:51:41.900581Z",
  "tags": [
    {
      "category": "PROMOTER",
      "name": "Price"
    },
    {
      "category": "PASSIVE",
      "name": "Service"
    }
  ],
  "survey": {
    "id": 2134,
    "attributes": {},
    "sent_date": "2017-11-27T17:51:12.879462Z"
  },
  "status": "OPEN",
  "status_changed": "2018-01-04T19:05:36.127721Z"
}

Path Params

feedback_id
int32
required

The id of the feedback you'd like to retrieve

Query Params

survey__contact__email
string

Search for all feedback from a specific contact by using their email address

score
int32

Choose to get feedback with specific scores. 0 - 10

score_type
string

Filter feedback by specific score types. Ex: promoter, passive, detractor

survey__campaign
int32

The id of the campaign you'd like all feedback from

survey__campaign__status
string

Filter feedback by their campaign statuses, Ex: ACTIVE, COMPLETE

followup__type
string

Get feedback based on the actions already taken on them. Options: REPLIED, FORWARDED

status
string

Add this parameter if you'd like to only view feedback that is either OPEN or CLOSED.

posted_date_1
date

Use this parameter to get all feedback before a specific date. Ex: 2016-10-23

posted_date_0
date

Use this parameter to get all feedback after a specific date. Ex: 2016-10-21

Headers

Authorization
string
required

This is where you'll provide your API key, after inserting the word 'Token' and a space

Content-Type
string
required

Must be "application/json"

 

Since there may be feedback in different campaigns, feedback can be queried by campaign_id, show only open feedback, filter by score type, along with a few more options as query parameters.
Ex: /api/feedback/?score=10

When this call is made, it will return 100 results at a time and will require paginating through the results. To paginate, you would add a page parameter to the url. Ex: <api_call>/api/feedback/?page=3

Feedback can be queried by specific time periods using date queries in the URL. All dates are using UTC time. Due to this, there may be a slightly different number of feedbacks than what's displayed on the campaign's dashboard since the dashboard respects user timezone settings. Date formats accepted are yyyy-mm-dd and mm/dd/yyyy.

Date Examples

All feedback before a specific date: /api/feedback/?posted_date_1=2016-10-23

All feedback after a specific date: /api/feedback/?posted_date_0=2016-10-31

Feedback for a specific time period: /api/feedback/?posted_date_0=2016-10-03&posted_date_1=2016-10-23

Suggest Edits

Get feedback by id

 
gethttps://app.promoter.io/api/v2/feedback/feedback_id/
curl --include \
     --header "Authorization: Token YOUR_API_KEY" \
     --header "Content-Type: application/json" \
  'https://app.promoter.io/api/v2/feedback/12445/'
var request = new XMLHttpRequest();

request.open('GET', 'https://app.promoter.io/api/v2/feedback/{feedback_id}/
');

request.setRequestHeader('Authorization', 'Token YOUR_API_KEY');
request.setRequestHeader('Content-Type', 'application/json');

request.onreadystatechange = function () {
  if (this.readyState === 4) {
    console.log('Status:', this.status);
    console.log('Headers:', this.getAllResponseHeaders());
    console.log('Body:', this.responseText);
  }
};

request.send();
from urllib2 import Request, urlopen

headers = {
  'Authorization': 'Token YOUR_API_KEY',
  'Content-Type': 'application/json'
}
request = Request('https://app.promoter.io/api/v2/feedback/{feedback_id}/
', headers=headers)

response_body = urlopen(request).read()
print response_body
require 'rubygems' if RUBY_VERSION < '1.9'
require 'rest_client'

headers = {
  :authorization => 'Token YOUR_API_KEY',
  :content_type => 'application/json'
}

response = RestClient.get 'https://app.promoter.io/api/v2/feedback/{feedback_id}/
', headers
puts response
// Maven : Add these dependecies to your pom.xml (java6+)
// <dependency>
//     <groupId>org.glassfish.jersey.core</groupId>
//     <artifactId>jersey-client</artifactId>
//     <version>2.8</version>
// </dependency>
// <dependency>
//     <groupId>org.glassfish.jersey.media</groupId>
//     <artifactId>jersey-media-json-jackson</artifactId>
//     <version>2.8</version>
// </dependency>

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;

Client client = ClientBuilder.newClient();
Response response = client.target("https://app.promoter.io/api/v2/feedback/{feedback_id}/
")
  .request(MediaType.APPLICATION_JSON_TYPE)
  .header("Authorization", "Token YOUR_API_KEY")
  .get();

System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));
//Common testing requirement. If you are consuming an API in a sandbox/test region, uncomment this line of code ONLY for non production uses.
//System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

//Be sure to run "Install-Package Microsoft.Net.Http" from your nuget command line.
using System;
using System.Net.Http;

var baseAddress = new Uri("https://app.promoter.io/api/v2/feedback/{feedback_id}/");

using (var httpClient = new HttpClient{ BaseAddress = baseAddress })
{

  httpClient.DefaultRequestHeaders.TryAddWithoutValidation("authorization", "Token YOUR_API_KEY");
  
  
  using(var response = await httpClient.GetAsync("undefined"))
  {
 
        string responseData = await response.Content.ReadAsStringAsync();
  }
}
<?php
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://app.promoter.io/api/v2/feedback/{feedback_id}/
");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
  "Authorization: Token YOUR_API_KEY",
  "Content-Type: application/json"
));

$response = curl_exec($ch);
curl_close($ch);

var_dump($response);
A binary file was returned

You couldn't be authenticated

{
  "id": 2387271,
  "href": "https://app.promoter.io/api/v2/feedback/12445/",
  "followup_href": "https://app.promoter.io/org/3925/campaign/23239/responses/all/response/12445/",
  "contact": {
    "attributes": {},
    "first_name": "Kate",
    "last_name": "Mac",
    "id": 23127796,
    "email": "kate@mac.com"
  },
  "campaign": {
    "id": 23239,
    "name": "My NPS Campaign",
    "launch_date": "2017-11-03T18:27:23Z",
    "status": "ACTIVE"
  },
  "score": 9,
  "created": "2017-11-27T17:51:41.900581Z",
  "score_changed": "2018-01-04T19:32:04.424509Z",
  "score_type": "promoter",
  "comment": "I love my new tablet! The price was great, but couldn't find anyone to help.",
  "comment_created": "2017-11-27T17:53:32.675321Z",
  "comment_modified": "2017-11-27T17:51:41.900581Z",
  "tags": [
    {
      "category": "PROMOTER",
      "name": "Price"
    },
    {
      "category": "PASSIVE",
      "name": "Service"
    }
  ],
  "survey": {
    "id": 2134,
    "attributes": {},
    "sent_date": "2017-11-27T17:51:12.879462Z"
  },
  "status": "OPEN",
  "status_changed": "2018-01-04T19:05:36.127721Z"
}

Path Params

feedback_id
int32
required

The id of the feedback you'd like to retrieve

Headers

Authorization
string
required

This is where you'll provide your API key, after inserting the word 'Token' and a space

Content-Type
string
required

Must be "application/json"

 

Retrieves a specific feedback in your organization by providing the feedback id.

Suggest Edits

Delete feedback

 
deletehttps://app.promoter.io/api/v2/feedback/feedback_id/
curl -X DELETE --include --header "Authorization: Token YOUR_API_KEY" --header "Content-Type: application/json" 'https://app.promoter.io/api/v2/feedback/1600/'
A binary file was returned

You couldn't be authenticated

Path Params

feedback_id
int32
required

The id of the feedback to be deleted.

Headers

Authorization
string
required

This is where you'll provide your API key, after inserting the word 'Token' and a space

Content_Type
string
required

Must be "applciation/json"

 

This action will permanently delete a piece of feedback.

Suggest Edits

Close feedback

 
puthttps://app.promoter.io/api/v2/feedback/feedback_id/
  curl --include \
  	 --request PUT \
     --header "Authorization: Token YOUR_API_KEY" \
     --header "Content-Type: application/json" \
     --data-binary "{
    	\"status\":\"CLOSED\"
		}" \
  'https://app.promoter.io/api/v2/feedback/123345/'
A binary file was returned

You couldn't be authenticated

{
  "id": 123345,
  "href": "https://app.promoter.io/api/v2/feedback/123345/",
  "followup_href": "https://app.promoter.io/org/3925/campaign/23239/responses/all/response/123345/",
  "contact": {
    "attributes": {},
    "first_name": "",
    "last_name": "",
    "id": 23127796,
    "email": "kate@mac.com"
  },
  "campaign": {
    "id": 23239,
    "name": "My Campaign",
    "launch_date": "2017-11-03T18:27:23Z",
    "status": "ACTIVE"
  },
  "score": 9,
  "score_created": "2017-11-27T17:51:41.900581Z",
  "score_modified": "2018-01-04T19:04:35.972457Z",
  "score_type": "promoter",
  "comment": null,
  "comment_created": null,
  "comment_modified": null,
  "tags": [
    {
      "category": "PROMOTER",
      "name": "price"
    }
  ],
  "survey": {
    "attributes": {},
    "sent_date": "2017-11-27T17:51:12.879462Z"
  },
  "status": "CLOSED",
  "status_changed": "2017-12-22T00:10:00Z"
}

Path Params

feedback_id
int32
required

The id of the feedback to be updated

Body Params

status
string
required

The status of the feedback being 'OPEN' or 'CLOSED'.

Headers

Authorization
string
required
Content-Type
string
required

Must be 'application/json'

 

Using this API call will allow you to update the status of a feedback. You have the options to update the feedback to 'OPEN' or 'CLOSED.

Suggest Edits

Reply to feedback

 
posthttps://app.promoter.io/api/v2/feedback/feedback_id/reply/
curl --include \
     --request POST \
     --header "Content-Type: application/json" \
     --header "Authorization: Token YOUR_API_KEY" \
     --data-binary "{
    \"from_user\": \"user@email.com\",
    \"message\": \"My response.\",
    \"cc\": [\"kate@mac.com\", \"mark@mac.com\"],
    \"bcc\": [\"joe@mac.com\"]
    }" \
'https://app.promoter.io/api/v2/feedback/1234/reply/'
A binary file was returned

You couldn't be authenticated

{ }
{"non_field_errors":["Reply already exists for this feedback."]}

Path Params

feedback_id
int32
required

The id of the feedback you want to reply to.

Body Params

from_user
string
required

Email of the user sending the reply.

message
string
required

The message you want to send as your reply.

cc
array of strings

A list of emails you want to be cc'd on the reply.

bcc
array of strings

A list of emails you want to be bcc'd on the reply.

Headers

Content-Type
string
required

Must be 'application/json'

Authorization
string
required

This is where you'll provide your API key, after inserting the word 'Token' and a space

 

This endpoint will allow you to follow-up with your contacts and reply to their feedback.

You'll need to provide the feedback_id to which you're replying to, who's email the reply is coming from, and the message you want to send. The 'from_user' email must be an email that belongs to a member of the organization.

You also have to option to cc or bcc other addresses in your reply. There's no limit to how many emails that can be included, but they'll need to be in a list.

Suggest Edits

Forward feedback

 
gethttps://app.promoter.io/api/v2/feedback/feedback_id/forward/
curl --include \
     --request POST \
     --header "Content-Type: application/json" \
     --header "Authorization: Token YOUR_API_KEY" \
     --data-binary "{
    \"from_user\": \"user@email.com\",
    \"to\": \"bob@example.com\"
    }" \
'https://app.promoter.io/api/v2/feedback/1234/forward/'
A binary file was returned

You couldn't be authenticated

{ }
{"non_field_errors":["Reply already exists for this feedback."]}

{"non_field_errors":["Feedback has been marked complete."]}

Path Params

feedback_id
int32
required

The id of the feedback you're forwarding.

Body Params

from_user
string
required

Email of the user forwarding the feedback.

to
string
required

Email of the recipient.

Headers

Content-Type
string
required

Must be 'application/json'

Authorization
string
required

This is where you'll provide your API key, after inserting the word 'Token' and a space

 

This endpoint will allow you to forward a feedback.

You'll need to provide the feedback_id of the feedback you're forwarding, who's email the forward is coming from, and the message you want to send. The 'from_user' email must be an email that belongs to a member of the organization. Feedback can only be forwarded to one recipient at a time.

Why can't I forward?

A feedback can only be forwarded when it's not in a 'complete' status. You cannot forward a feedback when:

  1. A reply has been sent.
  2. The feedback has been marked as 'complete'.
Suggest Edits

Tag feedback

 
posthttps://app.promoter.io/api/v2/feedback/feedback_id/tag/
curl --include \
     --request POST \
     --header "Content-Type: application/json" \
     --header "Authorization: Token YOUR_API_KEY" \
     --data-binary "{
    \"name\": \"price\",
    \"category\": \"DETRACTOR\"
    }" \
'https://app.promoter.io/api/v2/feedback/1234/tag/'
A binary file was returned

You couldn't be authenticated

{"category":"DETRACTOR","name":"price"}

Path Params

feedback_id
int32
required

Id of the feedback you want to add a tag(s) to.

Body Params

name
string
required

The name of your tag.

category
string
required

The category/sentiment to apply to your tag.

 

This endpoint will allow you to add a tag to your feedback.

The category options are:

DETRACTOR - negative sentiment (red)
PASSIVE - neutral sentiment (yellow)
PROMOTER - postive sentiment (green)

Since this is a 'POST' action, each call will add on a tag to your feedback. Multiple tags with the same name cannot exist on a feedback.

e.g. Tag price => detractor and price => passive could not exist on the same feedback. It must be one or the other.

Suggest Edits

Create feedback

 
posthttps://app.promoter.io/api/v2/feedback/
curl --include \
     --request POST \
     --header "Content-Type: application/json" \
     --header "Authorization: Token YOUR_API_KEY" \
     --data-binary "{
   		"score":7,
   		"comment":"commment",
   		"campaign_id":1234,
   		"email":"kate@mac.com",
   		"first_name": "Kate",
   		"last_name": "Mac",
   		"status": "CLOSED",
   		"tags": [
        	{
            	"name": "price",
            	"category": "PROMOTER"
        	}
    	]
	}" \
'https://app.promoter.io/api/v2/feedback/'
A binary file was returned

You couldn't be authenticated

{
  "id": 100906,
  "href": "https://app.promoter.io/api/v2/feedback/100906/",
  "followup_href": "http://app.promoter.io/org/123/campaign/1234/responses/all/response/100906/",
  "contact": {
    "last_name": "Mac",
    "id": 1174254,
    "email": "kate@mac.com",
    "first_name": "Kate",
    "attributes": {
      "Reference": "123456",
      "Source": "Support Ticket",
      "plan": "bronze"
    }
  },
  "campaign": {
    "id": 1234,
    "name": "Pear Computer Subscribers",
    "launch_date": "2019-03-12T16:55:29Z",
    "status": "ACTIVE"
  },
  "score": 7,
  "created": "2019-04-03T20:01:12.836235Z",
  "score_changed": "2019-04-03T20:01:12.836270Z",
  "score_type": "passive",
  "comment": "commment",
  "comment_created": "2019-04-03 20:01:13.529103+00:00",
  "comment_modified": "2019-04-03 20:01:13.529446+00:00",
  "tags": [
    {
      "category": "PROMOTER",
      "name": "price"
    }
  ],
  "survey": {
    "id": 1697687,
    "attributes": {},
    "sent_date": "2019-04-03T20:01:12.811394Z"
  },
  "status": "CLOSED",
  "status_changed": "2019-04-03T20:01:14.186253Z"
}

Body Params

score
int32
required

Must be an integer from 0 - 10

comment
string
campaign_id
int32
required

ID of the campaign to post feedback to

email
string
required

Email of the contact to post feedback for.

first_name
string
last_name
string
status
string

Status of the feedback. Option of OPEN or CLOSED. If not stated, then will be OPEN by default.

tags
json

Attach the 'name' of your tag and the 'category' (PROMOTER, PASSIVE, DETRACTOR)

Headers

Content-type
string
required

Must be 'application/json'

Authorization
string
required

This is where you'll provide your API key, after inserting the word 'Token' and a space

 

When creating a feedback for a campaign, the minimum requirements are a score, email address, and campaign ID.

Passing in the 'status' of the feedback is optional and will be OPEN by default. Options are OPEN or CLOSED.

Tags can be applied during the creation of a feedback, but are not required. A 'name' of each tag needs to be given, and then a 'category' sentiment. Category options are PROMOTER, PASSIVE, DETRACTOR.

  • If a contact record does not exist for the email, then the endpoint will create a contact.

  • If contact attributes exist for the contact, then current contact attributes will still be saved with the creation of the feedback.

  • The endpoint will create a survey object to reference for the feedback. This is why you'll see survey object data returned in the response body.

Suggest Edits

Get contact lists

 
gethttps://app.promoter.io/api/lists/
curl --include \
     --header "Authorization: Token YOUR_API_KEY" \
     --header "Content-Type: application/json" \
  'https://app.promoter.io/api/lists/'
var request = new XMLHttpRequest();

request.open('GET', 'https://app.promoter.io/api/lists/
');

request.setRequestHeader('Authorization', 'Token YOUR_API_KEY');
request.setRequestHeader('Content-Type', 'application/json');

request.onreadystatechange = function () {
  if (this.readyState === 4) {
    console.log('Status:', this.status);
    console.log('Headers:', this.getAllResponseHeaders());
    console.log('Body:', this.responseText);
  }
};

request.send();
from urllib2 import Request, urlopen

headers = {
  'Authorization': 'Token YOUR_API_KEY',
  'Content-Type': 'application/json'
}
request = Request('https://app.promoter.io/api/lists/
', headers=headers)

response_body = urlopen(request).read()
print response_body
require 'rubygems' if RUBY_VERSION < '1.9'
require 'rest_client'

headers = {
  :authorization => 'Token YOUR_API_KEY',
  :content_type => 'application/json'
}

response = RestClient.get 'https://app.promoter.io/api/lists/
', headers
puts response
// Maven : Add these dependecies to your pom.xml (java6+)
// <dependency>
//     <groupId>org.glassfish.jersey.core</groupId>
//     <artifactId>jersey-client</artifactId>
//     <version>2.8</version>
// </dependency>
// <dependency>
//     <groupId>org.glassfish.jersey.media</groupId>
//     <artifactId>jersey-media-json-jackson</artifactId>
//     <version>2.8</version>
// </dependency>

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;

Client client = ClientBuilder.newClient();
Response response = client.target("https://app.promoter.io/api/lists/
")
  .request(MediaType.APPLICATION_JSON_TYPE)
  .header("Authorization", "Token YOUR_API_KEY")
  .get();

System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));
//Common testing requirement. If you are consuming an API in a sandbox/test region, uncomment this line of code ONLY for non production uses.
//System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

//Be sure to run "Install-Package Microsoft.Net.Http" from your nuget command line.
using System;
using System.Net.Http;

var baseAddress = new Uri("https://app.promoter.io/api/");

using (var httpClient = new HttpClient{ BaseAddress = baseAddress })
{

  httpClient.DefaultRequestHeaders.TryAddWithoutValidation("authorization", "Token YOUR_API_KEY");
  
  
  using(var response = await httpClient.GetAsync("undefined"))
  {
 
        string responseData = await response.Content.ReadAsStringAsync();
  }
}
<?php
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://app.promoter.io/api/lists/
");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
  "Authorization: Token YOUR_API_KEY",
  "Content-Type: application/json"
));

$response = curl_exec($ch);
curl_close($ch);

var_dump($response);
A binary file was returned

You couldn't be authenticated

{
  "id":1,                     
  "name":"My Contact List"    
}

Headers

Authorization
string
required

This is where you'll provide your API key, after inserting the word 'Token' and a space

Content-Type
string
required

Must be "application/json"

 

Retrieves all lists within your organization.

Suggest Edits

Get metrics

 
gethttps://app.promoter.io/api/v2/metrics/
curl --include \
     --header "Authorization: Token YOUR_API_KEY" \
     --header "Content-Type: application/json" \
  'https://app.promoter.io/api/v2/metrics/'
var request = new XMLHttpRequest();

request.open('GET', 'https://app.promoter.io/api/v2/metrics/
');

request.setRequestHeader('Authorization', 'Token YOUR_API_KEY');
request.setRequestHeader('Content-Type', 'application/json');

request.onreadystatechange = function () {
  if (this.readyState === 4) {
    console.log('Status:', this.status);
    console.log('Headers:', this.getAllResponseHeaders());
    console.log('Body:', this.responseText);
  }
};

request.send();
from urllib2 import Request, urlopen

headers = {
  'Authorization': 'Token YOUR_API_KEY',
  'Content-Type': 'application/json'
}
request = Request('https://app.promoter.io/api/v2/metrics/
', headers=headers)

response_body = urlopen(request).read()
print response_body
require 'rubygems' if RUBY_VERSION < '1.9'
require 'rest_client'

headers = {
  :authorization => 'Token YOUR_API_KEY',
  :content_type => 'application/json'
}

response = RestClient.get 'https://app.promoter.io/api/v2/metrics/
', headers
puts response
// Maven : Add these dependecies to your pom.xml (java6+)
// <dependency>
//     <groupId>org.glassfish.jersey.core</groupId>
//     <artifactId>jersey-client</artifactId>
//     <version>2.8</version>
// </dependency>
// <dependency>
//     <groupId>org.glassfish.jersey.media</groupId>
//     <artifactId>jersey-media-json-jackson</artifactId>
//     <version>2.8</version>
// </dependency>

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;

Client client = ClientBuilder.newClient();
Response response = client.target("https://app.promoter.io/api/v2/metrics/
")
  .request(MediaType.APPLICATION_JSON_TYPE)
  .header("Authorization", "Token YOUR_API_KEY")
  .get();

System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));
//Common testing requirement. If you are consuming an API in a sandbox/test region, uncomment this line of code ONLY for non production uses.
//System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

//Be sure to run "Install-Package Microsoft.Net.Http" from your nuget command line.
using System;
using System.Net.Http;

var baseAddress = new Uri("https://app.promoter.io/api/");

using (var httpClient = new HttpClient{ BaseAddress = baseAddress })
{

  httpClient.DefaultRequestHeaders.TryAddWithoutValidation("authorization", "Token YOUR_API_KEY");
  
  
  using(var response = await httpClient.GetAsync("undefined"))
  {
 
        string responseData = await response.Content.ReadAsStringAsync();
  }
}
<?php
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://app.promoter.io/api/v2/metrics/
");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
  "Authorization: Token YOUR_API_KEY",
  "Content-Type: application/json"
));

$response = curl_exec($ch);
curl_close($ch);

var_dump($response);
A binary file was returned

You couldn't be authenticated

{ 
    "href": "https://app.promoter.io/api/campaigns/123/", 
    "nps": 25,                                             
    "campaign_name": "My Campaign Name",                     
    "promoter_percentage": 25,                              
    "passive_percentage": 25,                               
    "detractor_percentage": 50,                             
    "score_analysis": "AT RISK",                             
    "feedback_count": 4,                                    
    "surveys_delivered_count": 33106,                       
    "surveys_scheduled_count": 2415,                        
    "followup_count": 2,                                    
    "followups_outstanding": 2,                            
    "followup_rate_percentage": "50",                      
    "feedback_rate_percentage": "30",                       
    "average_revenue_per_customer": 210,                        
    "short_term_revenue_at_risk": 210,                       
    "long_term_revenue_at_risk": 63,                        
    "potential_new_revenue": 63                             
} 

Query Params

posted_date_1
string

Use this parameter to get all metrics before a specific date. Ex: 2016-10-23

posted_date_0
string

Use this parameter to get all metrics after a specific date. Ex: 2016-10-21

Headers

Authorization
string
required

This is where you'll provide your API key, after inserting the word 'Token' and a space

Content-Type
string
required

Must be "application/json"

 

This endpoint will retrieve all current campaign metrics within your organization.

When retrieving metrics, the default is to show metrics for the past 30 days.

You can grab metrics for a specific time period by date queries in the URL. All dates are using UTC time. Due to this, you may see slightly different metrics than what's displayed on your dashboard since your dashboard respects your timezone settings. Date formats accepted are yyyy-mm-dd and mm/dd/yyyy.

Date Examples

All metrics before a specific date: /api/metrics/?posted_date_1=2016-10-23

All metrics after a specific date: /api/metrics/?posted_date_0=2016-10-31

Metrics for a specific time period: /api/metrics/?posted_date_0=2016-10-03&posted_date_1=2016-10-23

Score analysis values:

(-100) - (-1): "AT RISK"

0 - 49: "GOOD"

50 - 74: "EXCELLENT"

75 - 100: "WORLD CLASS"

Suggest Edits

Get common replies

 
gethttps://app.promoter.io/api/v2/replies/
curl --include \
     --header "Authorization: Token YOUR_API_KEY" \
     --header "Content-Type: application/json" \
  'https://app.promoter.io/api/v2/replies/'
A binary file was returned

You couldn't be authenticated

{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": 847,
      "title": "Passive - no comment",
      "reply": "Thank you for taking a moment to respond! We really appreciate your time and know you're busy. We're striving to improve our product and learn more from our customers.
 
 What is your number one issue that we're not addressing today? I wanted to check in and make sure you're well taken care of :)
 ",
      "category": {
        "id": 232,
        "name": "My Common Replies"
      }
    }
  ]
}

Headers

Authorization
string
required

This is where you'll provide your API key, after inserting the word 'Token' and a space

Content-Type
string
required

Must be "application/json"

 

View all of the Common Replies that exist for your organization.

id - The id of the common reply
title - The title of the common reply
reply - The message within the common reply
category.id - The id of the category that the common reply is -> within
category.name - The name of the category that the common reply is within.

Suggest Edits

Create a common reply

 
posthttps://app.promoter.io/api/v2/replies/
curl --include \
     --request POST \
     --header "Content-Type: application/json" \
     --header "Authorization: Token YOU_API_KEY" \
     --data-binary "{
    \"title\": \"Passive - no comment\",
    \"reply\": \"Thank you for taking a moment to respond! We really appreciate your time and know you're busy. We're striving to improve our product and learn more from our customers.
 
 What is your number one issue that we're not addressing today? I wanted to check in and make sure you're well taken care of :)
 \",
    \"category\": {
        \"name\": \"My Common Replies\"
    }
}" \
'https://app.promoter.io/api/v2/replies/'
A binary file was returned

You couldn't be authenticated

{"id":3299,"title":"Passive - no comment","reply":"Thank you for taking a moment to respond! We really appreciate your time and know you're busy. We're striving to improve our product and learn more from our customers. What is your number one issue that we're not addressing today? I wanted to check in and make sure you're well taken care of :)
 ","category":{"id":123,"name":"My Common Replies"}}

Body Params

title
string
required

A description or title for your common reply.

reply
string
required

This will be the main body of your common reply message.

category
object
category.name
string
required

The name of the common reply category in which you would like the reply saved under.

Headers

Authorization
string
required

This is where you'll provide your API key, after inserting the word 'Token' and a space

Content-Type
string
required

Must be "application/json"

 

Create a common reply within your organization. You'll be able to give your reply a message and a title, and have it stored within a category of your choosing.

If you choose a category name that does not exist, a new category will be created and store the common reply within it.

Suggest Edits

Delete a common reply

 
deletehttps://app.promoter.io/api/v2/replies/common_reply_id/
curl -X DELETE --include --header "Authorization: Token YOUR_API_KEY" --header "Content-Type: application/json" 'https://app.promoter.io/api/v2/replies/345/'
A binary file was returned

You couldn't be authenticated

No response examples available

Path Params

common_reply_id
int32
required

The "id" of the common reply you would like to delete.

 

This action will delete a common reply within your organization.

 
posthttps://app.promoter.io/api/v2/hooks
curl --include \
     --request POST \
     --header "Authorization: Token YOUR_API_KEY" \
     --header "Content-Type: application/json" \
     --data-binary "{
    \"event\":\"feedback.added_or_changed\",
    \"target\": \"https://requestb.in/140amoa1\"
}" \
'https://app.promoter.io/api/v2/hooks'
A binary file was returned

You couldn't be authenticated

{
	"id": 1,
  "event": "feedback.added_or_changed",
  "target": "https://requestb.in/140amoa1"
}

Body Params

event
string
required
target
string
required

The URL for the webhook to post to.

Headers

Content-Type
string
required

Must be 'application/json'

Authorization
string
required

This is where you'll provide your API key, after inserting the word 'Token' and a space

 

Webhooks can be set up in the Integrations section of your Promoter account.

Events we currently support

  • feedback.added_or_changed - Feedback was created or changed.
  • feedback.tags_added_or_changed - Feedback had a Tag added/updated/removed
  • feedback.status_changed - Status of a feedback changed
  • feedback.removed - Feedback was removed
  • metric.score_changed - NPS score changed for a given campaign
  • contact.unsubscribed - Contact unsubscribed
  • tag.merged - Tag was merged in a campaign via Tag Management
  • tag.removed - Tag was deleted from a campaign via Tag Management
  • tag.renamed - Tag was renamed from a campaign via Tag Management

Response Bodies

The requestbin.com URLs below can be generated from RequestBin.com. You can use the service to create a free HTTPS endpoint. Any HTTP requests sent to that endpoint will be recorded with the associated payload and headers so you can observe the data sent from our webhooks before configuring your application to accept it.

feedback.added_or_changed

This webhook will have a 15 minute delay. This is so a contact has plenty of time to leave a comment before we push data to another source.

{
  "hook": {
    "id": 84,
    "event": "feedback.added_or_changed",
    "target": "https://[YOUR ENDPOINT ID].x.requestbin.com"
  },
  "data": {
    "status": "OPEN",
    "comment": "Loved my new tablet!",
    "score_changed": "2017-12-29T18:31:30.433Z",
    "score": 10,
    "campaign": {
      "status": "ACTIVE",
      "launch_date": "2017-08-15T21:16:02Z",
      "id": 2070,
      "name": "Pear Computers"
    },
    "tags": [],
    "score_type": "promoter",
    "comment_created": "2017-12-29T18:31:30.429Z",
    "contact": {
      "attributes": {},
      "first_name": "Kate",
      "last_name": "Mac",
      "id": 1192319,
      "email": "kate@mac.com"
    },
    "survey": {
      "id": 1234,
      "attributes": {},
      "sent_date": "2017-12-29T18:31:00.230Z"
    },
    "followup_href": "http://app.promoter.io/org/327/campaign/2070/responses/all/response/12445/",
    "created": "2017-12-29T18:31:20.951Z",
    "comment_modified": "2017-12-29T18:31:30.429Z",
    "status_changed": "2017-12-29T18:31:20.951Z",
    "id": 12445
  }
}

feedback.tags_added_or_changed

{
  "hook": {
    "id": 122,
    "event": "feedback.tags_added_or_changed",
    "target": "https://[YOUR ENDPOINT ID].x.requestbin.com"
  },
  "data": {
    "status": "OPEN",
    "comment": "Support took too long to answer my questions.",
    "score_changed": "2017-12-24T04:54:05.867Z",
    "score": 8,
    "campaign": {
      "status": "ACTIVE",
      "launch_date": "2017-08-15T21:16:02Z",
      "id": 2070,
      "name": "My NPS Campaign"
    },
    "tags": [
      {
        "category": "PASSIVE",
        "name": "support"
      }
    ],
    "score_type": "passive",
    "comment_created": "2017-12-13T21:15:23Z",
    "contact": {
      "attributes": {
        "signed_up": "2014-12-12",
        "Plan": "gold"
      },
      "first_name": "Kate",
      "last_name": "Mac",
      "id": 1174538,
      "email": "kate@mac.com"
    },
    "survey": {
      "attributes": {
        "OrderId": 123456789
      },
      "sent_date": "2017-12-13T21:15:00.241Z"
    },
    "followup_href": "http://app.promoter.io/org/327/campaign/2070/responses/all/response/12445/",
    "created": "2017-12-13T21:15:19.498Z",
    "comment_modified": "2017-12-24T04:54:05.857Z",
    "status_changed": "2017-12-13T21:15:19.498Z",
    "id": 12445
  }
}

feedback.status_changed

{
  "hook": {
    "id": 122,
    "event": "feedback.status_changed",
    "target": "https://[YOUR ENDPOINT ID].x.requestbin.com"
  },
  "data": {
    "status": "CLOSED",
    "comment": "Support took too long to answer my questions.",
    "score_changed": "2017-12-24T04:54:05.867Z",
    "score": 8,
    "campaign": {
      "status": "ACTIVE",
      "launch_date": "2017-08-15T21:16:02Z",
      "id": 2070,
      "name": "My NPS Campaign"
    },
    "tags": [
      {
        "category": "PASSIVE",
        "name": "support"
      }
    ],
    "score_type": "passive",
    "comment_created": "2017-12-13T21:15:23Z",
    "contact": {
      "attributes": {
        "signed_up": "2014-12-12",
        "Plan": "gold"
      },
      "first_name": "Kate",
      "last_name": "Mac",
      "id": 1174538,
      "email": "kate@mac.com"
    },
    "survey": {
      "attributes": {
        "OrderId": 123456789
      },
      "sent_date": "2017-12-13T21:15:00.241Z"
    },
    "followup_href": "http://app.promoter.io/org/327/campaign/2070/responses/all/response/12445/",
    "created": "2017-12-13T21:15:19.498Z",
    "comment_modified": "2017-12-24T04:54:05.857Z",
    "status_changed": "2017-12-13T21:15:19.498Z",
    "id": 12445
  }
}

feedback.removed

{
  "hook": {
    "id": 83,
    "event": "feedback.removed",
    "target": "https://[YOUR ENDPOINT ID].x.requestbin.com"
  },
  "data": {
    "status": "OPEN",
    "comment": "I loved my tablet and the price!",
    "score_changed": "2018-01-03T20:35:13.991Z",
    "score": 10,
    "campaign": {
      "status": "ACTIVE",
      "launch_date": "2017-08-15T21:16:02Z",
      "id": 2070,
      "name": "Pear Computers"
    },
    "tags": [
      {
        "category": "PROMOTER",
        "name": "price"
      }
    ],
    "score_type": "promoter",
    "comment_created": "2018-01-03T20:34:43.687Z",
    "contact": {
      "attributes": {},
      "first_name": "Kate",
      "last_name": "Mac",
      "id": 1174602,
      "email": "kate@mac.com"
    },
    "survey": {
      "attributes": {},
      "sent_date": "2017-11-10T20:56:00.252Z"
    },
    "followup_href": "https://app.promoter.io/org/327/campaign/2070/responses/all/response/12445/",
    "created": "2017-11-10T20:57:16Z",
    "comment_modified": "2018-01-03T20:34:43.687Z",
    "status_changed": "2017-12-06T17:41:22Z",
    "id": 12445
  }
}

metric.score_changed

{
  "hook": {
    "target": "https://[YOUR ENDPOINT ID].x.requestbin.com",
    "id": 251,
    "event": "metric.score_changed"
  },
  "data": {
    "potential_new_revenue": 73,
    "average_revenue_per_customer": 123,
    "formatted_long_term_revenue_at_risk": 73,
    "campaign_name": "Pear Computers",
    "followups_outstanding": 5,
    "promoter_percentage": 34,
    "formatted_potential_new_revenue": 73,
    "followup_rate_percentage": 17,
    "followup_count": 1,
    "formatted_surveys_scheduled_count": "0",
    "surveys_scheduled_count": 0,
    "formatted_surveys_delivered_count": "0",
    "score_analysis": GOOD,
    "detractor_percentage": 33,
    "formatted_average_revenue_per_customer": 0,
    "long_term_revenue_at_risk": 0,
    "passive_percentage": 0,
    "surveys_delivered_count": 10,
    "nps": 1,
    "feedback_count": 6,
    "formatted_short_term_revenue_at_risk": 123,
    "feedback_rate_percentage": 60,
    "short_term_revenue_at_risk": 123
  }
}

contact.unsubscribed

{
  "hook": {
    "target": "https://[YOUR ENDPOINT ID].x.requestbin.com",
    "id": 249,
    "event": "contact.unsubscribed"
  },
  "data": {
    "attributes": {    
    	"plan": "bronze"
    },
    "first_name": "Kate",
    "last_name": "Bell",
    "id": 12345,
    "email": "kate@mac.com"
  }
}

tag.merged

{
   "hook": {
     "target": "https://[YOUR ENDPOINT ID].x.requestbin.com",
     "id": 249,
     "event": "tag.merged"
   },
   "data": {
          “campaign” : {
               “id”: 1234,
               “Name”: “My NPS Campaign”
          }
          "before":"too expensive",
          "after":"price"
      }
   }
}

tag.removed

{
   "hook": {
     "target": "https://[YOUR ENDPOINT ID].x.requestbin.com",
     "id": 249,
     "event": "tag.removed"
   },
   "data": { 
        “campaign”: {
            “id” : 124,
            “Name”: “My NPS Campaign”,
        }
     "name" : “price”
   }
}

tag.renamed

{
   "hook": {
     "target": "https://[YOUR ENDPOINT ID].x.requestbin.com",
     "id": 249,
     "event": "tag.renamed"
   },
   "data": {
          “campaign” : {
               “id”: 1234,
               “Name”: “My NPS Campaign”
          }
          "before":"too expensive",
          "after":"price"
      }
   }
}