API Reference

HappyOrNot API for feedback data is based on HTTP REST. It has been designed with ease of use in mind and therefore we have selected widely-used and openly available techniques/technologies.

The URL for the API is

https://api.happy-or-not.com/v1/

Data Formats

The API currently supports only UTF-8 encoded JSON as data format for both the input and the output. With every request you should set the Content-Type header.

Besides using the data types supported by JSON, the following rules apply.

Correct value for Content-Type HTTP header

Content-Type: application/json; charset=UTF-8

Date and time-related data follows ISO8601-standard:

Date
yyyy-MM-dd
Time
HH:mm:ss
Timestamp
yyyy-MM-ddTHH:mm:ss.SSSZ, where time zone is either ±HHmm or 'Z' for ±00:00 (UTC).

Date is formatted in ISO8601

2013-05-30 14:33:00 2013-05-30T14:33:00.000+0200

Authentication

The API is only accessible using secure HTTPS-connections.

A Client ID and API Token are required for accessing API resources. Users with an administrative role are able to view, create and remove these company-wide API credentials in the HappyOrNot reporting service Admin view. If you don't have access to the HappyOrNot Reporting service you should ask your HappyOrNot contact or our support at support@happy-or-not.com.

In authentication error cases the API will return appropriate response (HTTP 401 Unauthorized).

The API provides two authentication methods:

HTTP Basic Authentication

When using Basic Authentication, use the client identifier as username and API token as password.

Example

GET /v1/folders HTTP/1.1 Content-Type: application/json; charset=UTF-8 Authorization: Basic Tm1JMk16ZzROemxqWldWaHpnNE46Tm1JMk16ZzROemxqWldWaHpnNE4=

HTTP Headers

The API has two headers reserved for authentication: X-HON-Client-Id and X-HON-API-Token.

Example

GET /v1/folders HTTP/1.1 Content-Type: application/json; charset=UTF-8 X-HON-Client-Id: NmI2Mzg4NzljZWVhzg4N X-HON-API-Token: Tm1JMk16ZzROemxqWldWaE1EWmpORGhpmxqWldWW

Endpoints / Versions

The API is accessed using a single endpoint defined by the following domain name. Note that the domain name might have been mapped to multiple IP addresses and those IP addresses may change at any given time. So you should use only the domain name.

API endpoint

https://api.happy-or-not.com

The base URL is followed by versioning information: "vX", where X is the number of the API version. The current version is v1.

https://api.happy-or-not.com/v1

Error Handling

In case of situations such as missing parameters, unauthorized access or server errors, the API will respond with an appropriate HTTP status code and the response body containing details in JSON-format.

List of common error codes

400 - Bad request 401 - Unauthorized 404 - Not found 500 - Server error

Rate Limiting

To make sure that the API is not affected by misuse, requests will be rate limited. The limit (10000 requests in hour) should be fairly high for authorized access and should not affect normal use. Every response will contain HTTP headers that will help caller to work within the limits.

Example response

HTTP/1.1 200 OK X-Hon-RateLimit-Limit: 10000 X-Hon-RateLimit-Remaining: 9999

Response delivery

HTTP response to any HTTP request sent to the endpoints described in this document may be gzipped if the client supports it (= sends header "Accept-Encoding: gzip,deflate" in request). The response will be gzipped if the response size exceeds 1400 bytes (otherwise it will fit into single TCP packet). The header "Transfer-Encoding: chunked" is also added if the response is large enough.

Fetching feedback results

Data model description

In the HappyOrNot-system customers' organizational aspects are structured hierarchically in a tree of folders. These folders are used to represent abstract and physical locations, business areas, stores and offices, etc. Folders can contain surveys that determine when a certain question is used and how the collected feedback is displayed. So the HappyOrNot feedback results are available via surveys.

Fetching results

Results can be fetched per survey object by its identifier and optional parameters that control result set precision and time period. To get survey identifiers, you first have to call the folders resource with parameter 'surveys' set to 'true'. The response contains a list of folder objects with an array of surveys if any have been assigned to the folder. Note that only leaf level folders can contain surveys. The survey's identifier is its property 'key'.

Hint: Call the folder resource recursively to gather an array of all accessible surveys. If a folder has subfolders, they will be included in property 'folders'.

Once the required survey keys have been fetched, feedback results can be fetched from the survey resource. Without additional parameters results from previous 14 days at daily precision are returned.

Example of how to fetch results

Fetch surveys of a folder:

https://api.happy-or-not.com/v1/folders?surveys=true

Response:

{ "key": 123, "name": "ExampleRootFolder", "folders": [ { "key": 124, "name": "ExampleSubFolder1", "surveys": [ { "key": 1234, "question": { "key": 12345, "name": "How was your day?", "locale": "en-US" }, "timeZone": "UTC", "activePeriods": [ { "start": "2016-01-01T00:00:00.000Z", "end": "2017-01-01T00:00:00.000Z" }], "surveyType": "TERMINAL" }, ... ] }, ... ] }

Fetch results for survey 1234:

https://api.happy-or-not.com/v1/surveys/1234/results

Response:

[ { "ts": "2016-06-01T00:00:00.000Z", "data": [4,8,12,16] }, { "ts": "2016-05-02T00:00:00.000Z", "data": [7,5,23,37] }, ... ]

Resources

Folders

Folders provide structure and hierarchy for various aspects, such as surveys and users, of the HappyOrNot-system.

Please note that the folders endpoint does not return all of the folders. It returns only the folder structure two levels down, so only immediate children, and their children, of the requested folder are returned. The /v1/folders/:key endpoint can be used to get rest of the folders.

Summary of available resource patterns

Folder JSON presentation of folder.

Properties

key
The identifier of the folder
name
The name of the folder
folders
An array of folders belonging to the folder (i.e. sub-folders). If a folder does not have sub-folders, this property is not included in the result.
surveys
An array of surveys belonging to the folder. If no surveys are requested or the folder does not contain any surveys, this property is not included in the result.

Example JSON objects

Folder containing two sub-folders.

{ "key": 1, "name": "Acme", "folders": [ { "key": 2, "name": "Tampere" }, { "key": 3, "name": "New York" }] }

GET /v1/folders Retrieves information on company's root folder.

Parameters

surveys
optional, either true or false
When true, folders will include a list of surveys belonging to them.
state
optional, one of: active, ended, starting
When this is given and the surveys-parameter is true, folders will include only the list of surveys in the given state.

Result

Success
Folders
Error
HTTP status code 404 when no folder is found.

Example requests and responses

GET /v1/folders

{ "key": 1, "name": "How was your day?", }

GET /v1/folders?surveys=true

{ "key": 1, "name": "Acme", "folders": [ { "key": 2, "name": "Tampere", "surveys": [{ "key": 2, "question": { "key": 1, "name": "How was your day?", "locale": "en-US" }, "timeZone": "Europe/Helsinki" }] },{ "key": 3, "name": "New York" } ], "surveys": [{ "key": 2, "question": { "key": 1, "name": "How was your day?", "locale": "en-US" }, "timeZone": "America/New_York" }] }

GET /v1/folders/:key Retrieves information on folder specified by key.

Parameters

key
required, identifier of folder
surveys
optional, either true or false
When true, folder-objects will include a list of surveys belonging to them.
state
optional, one of: active, ended, starting
When this is given and the surveys-parameter is true, folders will include only the list of surveys in the given state.

Result

Success
Folder
Error
HTTP status code 404 when no folder is found.

Examples

GET /v1/folders/3?surveys=true&state=active

{ "key": 3, "name": "Tampere", "folders": [{ "key": 4, "name": "Hervanta", "surveys": [{ "key": 2, "question": { "key": 1, "name": "How was your day?", "locale": "en-US" }, "timeZone": "UTC" }] }], "surveys": [{ "key": 1, "question": { "key": 1, "name": "How was your day?", "locale": "en-US" }, "timeZone": "UTC" }] }

GET /v1/folders/:key/children Lists sub-folders of a specified folder.

Parameters

key
required, identifier of folder
surveys
optional, either true or false
When true, folder-objects will include a list of surveys belonging to them.
state
optional, one of: active, ended, starting
When this is given and the surveys-parameter is true, folders will include only the list of surveys in the given state.
offset
optional, zero-based numeric value
The index of first result returned and used to paginate results.
limit
optional, numeric value in range 1..100
The number of results returned and used to paginate results Default value is 50 and maximum 100.

Result

Success
Object containing two properties: meta for additional information (of pagination etc.) and data for a list of folders.
Error
HTTP status code 404 when no folder is found.

Examples

GET /v1/folders/1/children

{ "meta": { "offset": 0, "limit": 50, "total": 2 }, "data": [{ "key": 3, "name": "Tampere" }, { "key": 4, "name": "Helsinki" }] }

Surveys and Results

Surveys determine when a certain question is used and how the collected feedback is displayed. The results are available via the survey resource.

Summary of available resource patterns

Survey JSON presentation of survey.

Properties

key
The identifier of the survey
question
Object of the question in default locale.
folder
Object of the folder where survey is located.
timeZone
The time zone of survey in "Area/Location"-format.
activePeriods
An array of objects with two properties, start and end, describing time periods when the survey is active. Start timestamp is inclusive and end is exclusive. If survey does not have any periods, this property is not included.
surveyType
A string representing the survey’s type. Possible values are: TERMINAL and WEB. surveyType is TERMINAL for surveys collecting feedback using Smiley Terminals and WEB for surveys collecting feedback using Web Smileys.

Example JSON objects

Survey with two active periods.

{ "key": 1, "question": { "key": 2, "name": "How was your day?", "locale": "en-US" }, "folder": { "key": 5, "name": "Tampere", }, "timeZone": "Europe/Helsinki", "activePeriods": [ { "start": "2013-01-01T00:00:00.000+0200", "end": "2013-02-01T00:00:00.000+0200" }, { "start": ""2013-03-01T00:00:00.000+0200"", "end": ""2013-04-01T00:00:00.000+0300"" }], "surveyType": "TERMINAL" }

OpenFeedback JSON presentation of open feedback.

Properties

Note: HappyOrNot might append more properties to this object in the future without api version increase. Consider implementing your API integration to allow this object to have more properties (or nested properties) than listed below.
ts
Timestamp in survey time zone
r
Index. Smiley button used when feedback was given. Number from 0 (very negative) to 3 (very positive).
relevance
Optional, Float from 0.0 (worst) to 1.0 (best). Automatically analyzed quality value for the open feedback text.
spam
Optional, true or false. true if feedback is marked as spam.
f
Optional, FollowUp object. The follow-up that was chosen when feedback was given. Will not be present if follow-ups are disabled, user did not choose any or if device does not support them.
text
The open feedback text

Example JSON objects

Positive feedback given after pressing the green button and choosing a follow-up

{ "ts": "2018-11-27T17:09:34.421+02:00", "r": 3, "relevance": 1, "spam": false, "f": { "key": 4, "name": "Taste of food" }, "text": "The dish was prepared perfectly!" }

Negative feedback given after pressing the red button and choosing a follow-up

{ "ts": "2018-11-27T17:10:45.123+02:00", "r": 0, "relevance": 0.92, "spam": false, "f": { "key": 1, "name": "Something else" }, "text": "Too expensive :(" }

Negative feedback given after pressing the red button without choosing a follow-up

{ "ts": "2018-11-27T19:12:01.965+02:00", "r": 0, "relevance": 1, "spam": false, "text": "Restaurant is one of the best in this area. I hope it would be open also on Sundays." }

Feedback categorized as spam

{ "ts": "2018-11-27T22:10:22.735+02:00", "r": 3, "relevance": 0.1, "spam": true, "text": "sdhfksjdhf" }

FollowUp JSON presentation of follow-up option.

Properties

Note: HappyOrNot might append more properties to this object in the future without api version increase. Consider implementing your API integration to allow this object to have more properties (or nested properties) than listed below.
key
Unique id of the follow-up option
name
Follow-up text in question's default locale

Example JSON objects

{ "key": 4, "name": "Taste of food" }

FollowUpResult JSON presentation of follow-up option results.

Properties

Note: HappyOrNot might append more properties to this object in the future without api version increase. Consider implementing your API integration to allow this object to have more properties (or nested properties) than listed below.

FollowUp object appended with results:

data
Responses. An array indexed from Very Unhappy (red button, index 0) to Very Happy (green button, index 3)
percentages
Relative amount compared to other follow-ups during the requested time period. Percentages are calculated separately for highlights and pain points.

Example JSON objects

{ "key": 4, "name": "Taste of food" "data": [ 17, 1, 0, 0 ], "percentages": [ 0.447, 0.026, 0.0, 0.0 ] }

RawResult JSON presentation of raw result.

Properties

Note: HappyOrNot might append more properties to this object in the future without api version increase. Consider implementing your API integration to allow this object to have more properties (or nested properties) than listed below.
ts
Timestamp in survey time zone
r
Optional index. Smiley button used when feedback was given. Number from 0 (Very Unhappy) to 3 (Very Happy). Not present for Web Smileys open feedback, see the o property below for more info.
data
Optional index array. Alternative to r. Hourly summed up results. The indexes in the array run from 0 (Very Unhappy) to 3 (Very Happy). See more when this is returned under /v1/surveys/:key/rawresults
f
Optional, FollowUp object. The follow-up that was chosen when feedback was given, if any.
o
Optional, partial OpenFeedback object. Always includes the text property. Web Smileys open feedback will also include the r button index as context what button response user gave when leaving the open feedback using Web Smileys. For Web Smileys, this nested r is provided instead of a root level r. This is because Web Smileys button response and open feedback are gathered separately and
Optional, partial OpenFeedback object. Always includes the text property. Web Smiley open feedbacks will also include the r button index as context what button response user gave when leaving the open feedback using the Web Smiley. For Web Smileys, this nested r is provided instead of a root level r. This is because Web Smiley button response and open feedback are gathered separately and the actual button response r is also returned as own RawResult object. Calculating them both as button responses would double the response. Having the nested r makes it possible to separate them when handling the results but still provides the important response context for the open feedback.

Example JSON objects

Basic raw result

{ "ts": "2018-07-12T11:49:33.182-02:00", "r": 3 }

Hourly summed result

{ "ts": "2018-07-13T11:00:00.000-02:00", "data": [ 4, 8, 12, 16 ] }

Raw Touch result with follow-up

{ "ts": "2018-04-21T12:06:42.343+01:00", "r": 2, "f": { "key": 3, "name": "Service" } }

Raw Touch result with follow-up and open feedback

{ "ts": "2018-04-21T13:06:43.162+01:00", "r": 0, "f": { "key": 3, "name": "Service" }, "o": { "text": "Not enough shop clerks. Did not get any service" } }

Open feedback from Web Smileys

{ "ts": "2016-11-18T12:15:43.362Z", "o": { "r": 1, "text": "The website is hard to navigate!" } }

GET /v1/surveys/:key Retrieves information for a specific survey.

Parameters

key
required, identifier of the survey

Result

Success
Survey
Error
HTTP status code 404 when no survey is found.

Example requests and responses

GET /v1/surveys/1

See above.

GET /v1/surveys/:key/results Retrieves feedback results for specific survey.

Parameters

key
required, identifier of the survey
date_start
optional, timestamp
Timestamp of returned feedback data is equal or later than the value. When precision is day or greater then date_start is exclusive. The default value depends on date_end and truncate parameters. truncate defines the length of the default period by the following rules:
  • year returns all results
  • month returns results for the current year
  • week returns results for the previous 2 months
  • day returns previous 14 days
  • hour returns previous 24 hours
date_end
optional, timestamp
Timestamp of returned feedback data is sooner than the value. For default values, see date_start
truncate
optional, year | month | week | day | hour
Case-insensitive value from one of the above. Truncates and sums the feedback to required precision. By default it is day. Maximum values are none for year, 7 days for hour and 12 months for the rest. To fetch more data, use additional requests.
Known bug!
If truncate = day is used or no truncate value given (defaults to day) the date_start will be exclusive. Therefore, one day must be subtracted from the value to get the expected result. This will be fixed for the next version of the API, but left as is in the current version.

Result

Success
Array of objects with ts for result timestamp and data for array of feedback. The array is indexed from Very Unhappy (red button, index 0) to Very Happy (green button, index 3). The actual indexes are dependent on how many active buttons the device has.
Error
HTTP status code 400 when date_end is before date_start or unknown value given for truncate. HTTP status code 404 when no survey is found.

Example requests and responses

GET /v1/surveys/3/results?truncate=hour
&date_start=2013-05-03T00:00:00.000Z&date_end=2013-05-04T00:00:00.000Z

[ { "ts": "2013-05-03T00:00:00.000Z", "data": [ 4, 8, 12, 16 ] }, { "ts": "2013-05-03T01:00:00.000Z", "data": [ 4, 8, 12, 16 ] }, { ... "ts": "2013-05-03T22:00:00.000Z", "data": [ 4, 8, 12, 16 ] }, { "ts": "2013-05-03T23:00:00.000Z", "data": [ 4, 8, 12, 16 ] }, { "ts": "2013-05-03T00:00:00.000Z", "data": [ 4, 8, 12, 16 ] }, ]

GET /v1/surveys/:key/openfeedback Retrieves open feedback for specific survey.

Parameters

key
required, identifier of the survey
date_start
optional, timestamp
Timestamp of returned survey open feedback data is equal or later than the value.
date_end
optional, timestamp
Timestamp of returned open feedback data is sooner than the value.

Result

Success

A single JSON object that contains meta and data keys. The data key contains an array of OpenFeedback objects. The meta key contains paging information, if the response does not contain all the results.

If there is so much feedback that some of it does not fit in the same HTTP response, the response will contain the feedback with the earliest timestamps. The maximum amount of open feedback returned in single response is 10 000. If there is more feedback available, then inside the meta key will be a moreResultsAfter key that will give you the timestamp from which to request more results with this same endpoint. This way you can retrieve any amount of feedback in several "pages".

Error
HTTP status code 400 in case of invalid parameters. HTTP status code 404 when no survey is found.

Example requests and responses

GET /v1/surveys/3/openfeedback?&date_start=2018-11-27T14:00:00.000Z&date_end=2018-11-27T23:00:00.000Z

{ "meta": {}, "data": [ { "ts": "2018-11-27T17:09:34.421+02:00", "relevance": 1.0, "spam": false, "r": 3, "f" { "key": 4, "name": "Taste of food" }, "text": "The dish was prepared perfectly!" }, { "ts": "2018-11-27T17:10:45.123+02:00", "relevance": 0.92, "spam": false, "r": 0, "f" { "key": 1, "name": "Something else" }, "text": "Too expensive :(" }, { "ts": "2018-11-27T19:12:01.965+02:00" "r": 0, "relevance": 1.0, "spam": false, "text": "Restaurant is one the best in this area. I hope it would be open also on Sundays." }, { "ts": "2018-11-27T22:10:22.735+02:00" "r": 3, "relevance": 0.1, "spam": true, "text": "sdhfksjdhf" } }

GET /v1/surveys/3/openfeedback?&date_start=2018-01-01T00:00:00.000Z&date_end=2019-01-01T00:00:00.000Z

{ "meta": { "moreResultsAfter": "2018-10-03T10:20:18.000Z" }, "data": [ ... circa 10000 open feedback objects ... ] }

GET /v1/surveys/:key/followup Retrieves follow-up results for a specific survey.

Parameters

key
required, identifier of the survey
date_start
optional, timestamp
Timestamp of returned survey follow-up result data is equal or later than the value.
date_end
optional, timestamp
Timestamp of returned follow-up result data is sooner than the value.

Result

Success
Object containing two properties:

meta for any additional information and data for the follow-up results.

data contains two arrays: painPoints for negative (red buttons) follow-ups and highlights for positive (green buttons) follow-ups.

Each array item is a FollowUpResult object

In the case where no follow-up responses were given during the requested period, empty painPoints and highlights arrays are returned. Either painPoints or highlights array can also be empty if there are no follow-up options configured for them, or if there are no negative or positive results during the requested period.

Note: HappyOrNot might append more properties to this respons in the future without api version increase. Consider implementing your API integration to allow the result to have more properties (or nested properties) than mentioned above.

Error
HTTP status code 400 in case of invalid parameters. HTTP status code 404 when no survey is found.

Example requests and responses

GET /v1/surveys/3/followup
&date_start=2018-05-03T00:00:00.000Z&date_end=2018-05-13T00:00:00.000Z

{ "meta": {}, "data": { "painPoints": [ { "key": 2, "name": "Waiting time", "data": [ 17, 1, 0, 0 ], "percentages": [ 0.447, 0.026, 0.0, 0.0 ] }, { "key": 20, "name": "Cleanliness", "data": [ 6, 1, 0, 0 ], "percentages": [ 0.158, 0.026, 0.0, 0.0 ] }, { "key": 1, "name": "Something else", "data": [ 4, 1, 0, 0 ], "percentages": [ 0.105, 0.026, 0.0, 0.0 ] }, { "key": 5, "name": "Food quality", "data": [ 4, 1, 0, 0 ], "percentages": [ 0.105, 0.026, 0.0, 0.0 ] }, { "key": 11, "name": "Accessibility", "data": [ 1, 2, 0, 0 ], "percentages": [ 0.026, 0.053, 0.0, 0.0 ] } ], "highlights": [ { "key": 42, "name": "Staff attitude", "data": [ 0, 0, 12, 94 ], "percentages": [ 0.0, 0.0, 0.069, 0.54 ] }, { "key": 4, "name": "Taste of food", "data": [ 0, 0, 4, 16 ], "percentages": [ 0.0, 0.0, 0.023, 0.092 ] }, { "key": 20, "name": "Cleanliness", "data": [ 0, 0, 9, 9 ], "percentages": [ 0.0, 0.0, 0.052, 0.052 ] }, { "key": 5, "name": "Food quality", "data": [ 0, 0, 6, 10 ], "percentages": [ 0.0, 0.0, 0.034, 0.057 ] }, { "key": 1, "name": "Something else", "data": [ 0, 0, 3, 11 ], "percentages": [ 0.0, 0.0, 0.017, 0.063 ] } ] } }

GET /v1/surveys/:key/rawresults Retrieves raw feedback results for a specific survey.

Description

It is possible to get raw results instead of summed up results. Raw results have a separate timestamp for each feedback. This allows getting the time of the feedback as accurately as possible. Raw data does not use the misuse filtering that the normal results use: if you compare the raw results to the normal results, they will not exactly match.

Most terminals are able to report the time of feedback at the accuracy of one second. Some Smiley Terminals can only report results summed up by the hour due to more limited technical capabilities or poor local network connectivity.

Also, in some situations some older devices might need to batch multiple results to the same timestamp, therefore it is possible that in some conditions there are multiple results that appear to be exactly the same, but are actually separate button presses given inside a short time period.

The accurate raw results are returned in JSON Objects like this: { "ts": "2013-05-03T06:15:43.000Z", "r": 3 } The Object represents one feedback. The individual response is returned as a number from 0 (Very Unhappy) to 3 (Very Happy).

The hourly summed up results are returned in a JSON Object like this: { "ts": "2013-05-03T06:00:0.000Z", "data": [ 4, 8, 12, 16 ] } The four numbers in the array are the counts of four types of feedback on a Smiley Terminal. The indexes in the array run from 0 (very negative) to 3 (very positive).

The response from this endpoint may contain both types of data objects in the same array of results returned.

If your terminals are not reporting the feedback times with sufficient accuracy, please contact HappyOrNot support or your HappyOrNot sales contact to see what can be done.

Parameters

key
required, identifier of the survey
date_start
optional, timestamp
Timestamp of returned feedback data is equal or later than the value. If the parameter is not present, data is returned from the beginning.
date_end
optional, timestamp
Timestamp of returned feedback data is sooner than the value. If the parameter is not present, data is returned to the end.
followup
optional, boolean
If true returns also the follow-up that was selected if the survey has follow-ups (e.g. survey with Smiley Touch). Default value is false.
openfeedback
optional, boolean
If true returns also the open feedback that was given if the survey supports open feedback (e.g. survey Smiley Touch and Web Smileys). Default value is false. Note: enabling open feedback has an effect on the maximum number of feedback returned (see below).

Result

Success
A single JSON object that contains meta and data keys. The data key contains an array of RawResult objects. The meta key contains paging information, if the response does not contain all the results.
If there is so much feedback that some of it does not fit in the same HTTP response, the response will contain the feedback with the earliest timestamps. The maximum amount of feedback returned in a single response will vary, but should always be over 100 000 if results do not contain any open feedback. If open feedback is requested, the amount of feedback returned in a single response is limited to 10 000. Inside the meta key will be a moreResultsAfter key that will give you the timestamp from which to request more results with this same endpoint. This way you can retrieve any amount of feedback in several "pages."
Error
Empty result data array when date_end is before date_start or if the dates are the same. HTTP status code 404 when no survey is found.

Example requests and responses

GET /v1/surveys/3/rawresults?date_start=2013-05-03T00:00:00.000Z&date_end=2013-05-04T00:00:00.000Z&openfeedback=true&followup=true

{ "meta": {}, "data": [ { "ts": "2013-05-03T00:15:43.000Z", "r": 3 }, { "ts": "2013-05-03T01:00:00.000Z", "data": [ 4, 8, 12, 16 ] }, { ... "ts": "2013-05-03T11:01:04.000Z", "r": 2 }, { "ts": "2013-05-03T12:14:03.122Z", "r": 0, "f": { "key": 3, "name": "Service" }, "o": { "text": "Bad service :(" } }, { "ts": "2013-05-03T12:18:01.456Z", "o": { "r": 1, "text": "The website is hard to navigate!" } } ] }

GET /v1/surveys/3/rawresults?date_start=2016-01-01T00:00:00.000Z&date_end=2017-01-01T00:00:00.000Z

{ "meta": { "moreResultsAfter": "2016-05-03T11:02:18.000Z" }, "data": [ { "ts": "2016-01-01T00:15:43.000Z", "r": 3 }, ... over 100000 result objects ... { "ts": "2016-05-03T11:02:17.000Z", "r": 2 } ] }

Questions

Questions define what has been asked to get the feedback. They give the meaning for the different feedback options. Questions are company-specific.

Summary of available resource patterns

Question JSON presentation of question.

Properties

key
The identifier of the question
name
The question
locale
IETF BCP 47-formatted language tag
The default language of the question. For example: en-US.

Example JSON objects

Single question without surveys

{ "key": 1, "name": "How was your day?", "locale": "en-US" }

GET /v1/questions Lists the company's questions.

Parameters

offset
optional, zero-based numeric value
The index of the first result returned and used to paginate results.
limit
optional, numeric value in range 1..100
The number of results returned and used to paginate results. Default value is 50 and maximum is 100.

Result

Success
Object containing two properties: meta for additional information (of pagination etc.) and data for a list of questions. Empty list when company does not have any questions.

Example requests and responses

GET /v1/questions?offset=0&limit=5

{ meta": { "offset": 0, "limit": 5, "total": 1 }, "data": [{ "key": 3, "name": "How was your day?", "locale": "en-US" }] }

GET /v1/questions/:key Retrieves a specific question.

Parameters

key
required, identifier of the question

Result

Success
Question
Error
HTTP status code 404 when no question is found.

Example requests and responses

GET /v1/questions/3

{ "key": 3, "name": "How was your day?", "locale": "en-US" }

GET /v1/questions/:key/surveys Lists surveys for specific question.

Parameters

key
required, identifier of the question
state
optional, one of: active, ended, starting
When present, the result only contains surveys in given state.
offset
optional, zero-based numeric value
The index of first result returned and used to paginate results.
limit
optional, numeric value in range 1..100
The number of results returned and used to paginate results Default value is 50 and maximum 100.

Result

Success
Object containing two properties: meta for additional information (of pagination etc.) and data for a list of surveys.
Error
HTTP status code 404 when no question is found.

Example requests and responses

GET /v1/questions/3/surveys

{ "meta": { "offset": 0, "limit": 50, "total": 4 }, "data": [{ "key": 1, "folder": { "key": 3, "name": "Tampere" }, "timeZone": "Europe/Helsinki", "activePeriods": [ { "start": "2013-01-01T00:00:00.000+0200", "end": "2013-02-01T00:00:00.000+0200" }, { "start": ""2013-03-01T00:00:00.000+0200"", "end": ""2013-04-01T00:00:00.000+0300"" }] }, { "key": 2, "folder": { "key": 4, "name": "London" }, "timeZone": "Europe/London", "activePeriods": [ { "start": "2013-01-01T00:00:00.000+0200", "end": "2013-02-01T00:00:00.000+0200" }, { "start": ""2013-03-01T00:00:00.000+0200"", "end": ""2013-04-01T00:00:00.000+0300"" }] }] }

Alerts

Alerts are triggered based on a survey's alert specifications. If responses given in defined time window meet the criteria of the alert specification, then an alert is triggered. Alert specifications can be edited in the web UI.

Alerts can be fetched for a folder and optionally also for any child folders.

Summary of available resource patterns

Alert JSON presentation of alert.

Properties

Note: HappyOrNot might append more properties to this object in the future without api version increase. Consider implementing your API integration to allow this object to have more properties (or nested properties) than listed below.
key
The identifier of the alert
alertType
A string representing the alert’s type. Possible values are: negative, indexThreshold and feedbackCount. More alert types might be added in the future without increasing api version.
survey
The survey that has the alert specification for this alert. Survey's results are monitored and alerts are triggered based on the alert specification that has been configured for the survey. Only a subset of a full Survey-object properties are provided here.
alertSpecification
The alert specification of this alert. Alert specifications are configured for folders using the web UI. Alerts that have same alert specification are occurances of same alert being triggered over time. Survey's results are monitored and alerts are triggered based on the alert specification. This value is useful for grouping alerts.
beginTime
Point of time when alert was opened/triggered. Timestamp with survey's timezone.
endTime
Optional. Point of time when alert was closed. Missing if alert is still open. Timestamp with survey's timezone.
parameters

Alert parameters. Parameters are a combination of the alert specification parameters and the actual calculated values that triggered the alert.

Some of the parameters are present only for certain alert types. Alert types that have the parameter are listed below the parameter description.

Alert specification's parameters (configuration values) included in each alert:

negative
true or false. Specifies if this alert was configured to be triggered by negative feedback.

negative|indexThreshold|feedbackCount

windowMin
Minutes. The time window of responses used to evaluate alert conditions.

negative|indexThreshold|feedbackCount

threshold
The threshold that needs to be reached for alert to be triggered. Semantics depend on the alert type.

negative|feedbackCount

countThreshold
Additional response count threshold.

negative|feedbackCount

thresholdType
String: under or over

indexThreshold

responseFilter
Index array. Indexes are from 0 (very negative) to 3 (very positive). Responses not in the filter are ignored for this alert.

feedbackCount

Value parameters calculated from responses during the time window:

responses
Count. How many responses were given during time window.

negative|indexThreshold|feedbackCount

actual
Actual value of the configured limit/threshold that was exceeded to trigger this alert. Semantics depend on the alert type.

negative|indexThreshold

negativeResponses
Count. Amount of negative responses during the time window.

negative

Example JSON objects

Index threshold alert

Alert is triggered when the index has been above or below a certain value over a specified time window

{ "key": 91236, "alertType": "indexThreshold", "beginTime": "2018-07-18T10:00:00.000-07:00", "endTime": "2018-07-23T16:15:00.000-07:00", "parameters": { "negative": true, "windowMin": 30, "responses": 13, "actual": 80, "threshold": 90, "thresholdType": "under" }, "alertSpecification": { "key": 8125 }, "survey": { "key": 10, "question": { "key": 312, "name": "How clean are our toilets today?", "locale": "en-US" }, "folder": { "key": 2, "name": "West entrance bathroom" }, "timezone": "America/Dawson_Creek" } }

Negative alert

Alert-triggering negative criteria are the set percentage of negative responses (dark and light red) and the associated time window (available window ranges are 15, 30, 60, 120, 140 minutes)

{ "key": 91234, "alertType": "negative", "beginTime": "2018-07-19T12:15:00.000-07:00", "endTime": "2018-07-19T13:15:00.000-07:00", "parameters": { "negative": true, "windowMin": 15, "responses": 100, "actual": 44, "negativeResponses": 44, "threshold": 33, "countThreshold": 10 }, "alertSpecification": { "key": 8123 }, "survey": { "key": 10, "question": { "key": 312, "name": "How clean are our toilets today?", "locale": "en-US" }, "folder": { "key": 2, "name": "West entrance bathroom" }, "timezone": "America/Dawson_Creek" } }

Feedback count alert

Alert is triggered when a specified limit of a certain type of feedback, or any combination of feedback, is met during a specified time window

{ "key": 91235, "alertType": "feedbackCount", "beginTime": "2018-07-19T14:00:00.000-07:00", "endTime": "2018-07-20T15:15:00.000-07:00", "parameters": { "negative": false, "windowMin": 15, "responses": 131, "countThreshold": 120, "responseFilter": [ 0, 1 ] }, "alertSpecification": { "key": 8124 }, "survey": { "key": 10, "question": { "key": 312, "name": "How clean are our toilets today?", "locale": "en-US" }, "folder": { "key": 2, "name": "West entrance bathroom" }, "timezone": "America/Dawson_Creek" } }

GET /v1/folders/:key/alerts Retrieves alert history of a folder.

Parameters

All the alerts that have been in open state between date_start and date_end are returned. Note that also alerts opened before date_start or closed after date_end will be included if their open period intersects with the given date range.
key
required, identifier of folder
child_folders
optional, either true or false
When true, returns also alerts for child folders.
date_start
optional, timestamp
Alerts with equal or later endTime timestamp than the date_start are included as well as all alerts with no endTime.
date_end
optional, timestamp
Alerts with beginTime timestamp lower than the date_end are included.
local_date_start
optional, timestamp without timezone

ISO8601-standard timestamp without timezone:
yyyy-MM-ddTHH:mm:ss.SSS

Works like date_start, but uses survey's time zone when comparing to alert's endTime and startTime.

Local date range is useful to:

  • Request alerts for certain local time (e.g. 3 pm) without having to know the time zone of the survey.
  • Request alerts for meaningful time periods, like full day, week or a month. E.g. local_date_start=2018-03-01T00:00:00.000&local_date_end=2018-04-01T00:00:00.000
  • Request alerts for a day, week or a month period of a folder with child folders that contain surveys in different time zones.

Local date range is alternative to date_start and date_end. It is not allowed to mix them or specify both ranges at the same time.
local_date_end
optional, timestamp without timezone

ISO8601-standard timestamp without timezone:
yyyy-MM-ddTHH:mm:ss.SSS

Works similar to date_end, but uses survey's time zone when comparing to alert's startTime and endTime.

Result

Success
A single JSON object that contains meta and data keys. The data key contains list of Alert objects. The meta key contains paging information, if the response does not contain all the results.
If there are so many alerts that some of them do not fit in the same HTTP response, the response will contain the alerts with the earliest beginTime timestamps. The maximum number of alerts returned in a single response is 10 000. Inside the meta key will be a moreResultsAfter key that will give you the timestamp from which to request more alerts with this same endpoint. This way you can retrieve any amount of alerts in several "pages".
Error
HTTP status code 404 when no folder is found.

Examples

GET /v1/folders/2/alerts?
date_start=2018-07-19T13:00:00.000-07:00&
date_end=2018-07-19T14:30:00.000-07:00

{ "meta": { }, "data": [ { "key": 91236, "alertType": "indexThreshold", "beginTime": "2018-07-18T10:00:00.000-07:00", "endTime": "2018-07-23T16:15:00.000-07:00", "parameters": { "negative": true, "windowMin": 30, "responses": 13, "actual": 80, "threshold": 90, "thresholdType": "under" }, "alertSpecification": { "key": 8125 }, "survey": { "key": 10, "question": { "key": 312, "name": "How clean are our toilets today?", "locale": "en-US" }, "folder": { "key": 2, "name": "West entrance bathroom" }, "timezone": "America/Dawson_Creek" } }, { "key": 91235, "alertType": "feedbackCount", "beginTime": "2018-07-19T14:00:00.000-07:00", "endTime": "2018-07-20T15:15:00.000-07:00", "parameters": { "negative": false, "windowMin": 15, "responses": 131, "countThreshold": 120, "responseFilter": [ 0, 1 ] }, "alertSpecification": { "key": 8124 }, "survey": { "key": 10, "question": { "key": 312, "name": "How clean are our toilets today?", "locale": "en-US" }, "folder": { "key": 2, "name": "West entrance bathroom" }, "timezone": "America/Dawson_Creek" } } ] }

GET /v1/folders/2/alerts?child_folders=true

{ "meta": { "moreResultsAfter": "2017-05-20T14:00:00.000Z" }, "data": [ { ... circa 10000 alert objects ... } ] }

GET /v1/folders/2/alerts?child_folders=true
local_date_start=2018-03-21T00:00:00.000&
local_date_end=2018-03-22T00:00:00.000

{ "meta": { }, "data": [ { ... all alerts that were open during local date 2018-03-21 for folder 2 or its child folders according to each survey's own time zone ... } ] }