About
Review Stream
Query for all the latest reviews of a given property to use in offline analysis. Filter these reviews by different criteria. Content provided by this API cannot be used for display purposes due to content restrictions.
Widget Review Stream
Query for all the latest reviews of a given property to use for display purposes, such as in a widget. Due to content licensing agreements with our partners, TripAdvisor and Yelp, we are unable to provide TripAdvisor and Yelp content through this endpoint.
Review Summary
The review summary provides you with critical data about your hotel. Key metrics can be analyzed over custom time periods and include:
New reviews volume
Average review rating
TripAdvisor rank
Additionally, see your volume breakdown by review site.
Sentiment Summary
Sentiment Analysis is a core Revinate feature that will help you quickly and easily assess the guest sentiment attributed to your hotels, as well as provide incredibly detailed insight into your operation. Sentiment Analysis goes beyond the review rating by looking at the detail of the reviews and identifying sentiment about various aspects of your operations.
We've tailored our Sentiment Analysis feature specifically for the hospitality industry. Collaborating closely with our customers, we've identified hundreds of the most important topics for hotels, and categorized them based on traditional operations and guest feedback categories.
Introduction
This document describes Revinate's REST API, available resources, supported methods, and expected behavior for requests, responses, and security.
Base URL
All Resources share the same base url: https://porter.revinate.com
Authentication and Access Control
Resources requiring authentication require the use of an API key and API secret (provided by Revinate), which are used to pass the following Authentication headers (sample values below):
X-Revinate-Porter-Username: test_user@revinate.com
X-Revinate-Porter-Timestamp: 1420765002
X-Revinate-Porter-Key: d87b88ceefbcf9d2b2adfb2bbbde1234
X-Revinate-Porter-Encoded: 753b2b64fc91ab26484d67b67eeae4f5588ce4d5b107346308a7421246c8fff8
- The
X-Revinate-Porter-Username
must be a username that has access to the resources requested and to the API key used. - The
X-Revinate-Porter-Timestamp
is an epoch seconds timestamp that must be within 5 minutes (before or after) of when the request was sent. - The
X-Revinate-Porter-Key
is the API key provided by Revinate. -
The
X-Revinate-Porter-Encoded
header is is a keyed-hash message authentication code using a SHA-256 crypto hash function (HMAC SHA256) encryption of the concatenated string:username + timestamp
using the API secret. The header is thusHMAC_SHA256(apiSecret, username + timestamp)
as per the specifications here HMAC
Below are some sample snippets for how to calculate the HMAC SHA256 using the API secret, username and timestamp
#!/bin/sh USERNAME=test_user@revinate.com SECRET=b7536617fa4a1a9e3c7a707abcde866771570cb8c9a28401abcde755b48be6cb TIMESTAMP=`date +%s` # Take hexdump of API Secret kSecret=$(printf "$SECRET" | xxd -p -c 256) # Use openssl to key-hash the username and timestamp using the secret as key # Make sure openssl is at least 1.0.0 ENCODED=$(printf "$USERNAME$TIMESTAMP" | openssl dgst -binary -hex -sha256 -mac HMAC -macopt hexkey:$kSecret | sed 's/^.* //')
import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.security.GeneralSecurityException; public class EncryptionUtil { public static String calculateHMAC(String secret, String username, int timestamp) { // Concatenate the username and timestamp (epoch seconds) String data = username + timestamp; try { // Encrypt data using the secret SecretKeySpec signingKey = new SecretKeySpec(secret.getBytes(), "HmacSHA256"); Mac mac = Mac.getInstance("HmacSHA256"); mac.init(signingKey); byte[] rawHmac = mac.doFinal(data.getBytes()); // encrypted data is a byte array convert back to string String encoded = ""; for (final byte element : rawHmac) { encoded += Integer.toString((element & 0xff) + 0x100, 16).substring(1); } return encoded; } catch (GeneralSecurityException e) { throw new IllegalArgumentException(); } } }
require "openssl" digest = OpenSSL::Digest::SHA256.new secret = "b7536617fa4a1a9e3c7a707abcde866771570cb8c9a28401abcde755b48be6cb" username = "test_user@revinate.com" timestamp = Time.now.to_i data = "#{username}#{timestamp}" encoded = OpenSSL::HMAC.hexdigest(digest, secret, data)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Security.Cryptography; namespace Revinate.Tools { class EncryptionUtil { public static String calculateHMAC(String secret, String username, int timestamp) { //Concatenate the username and timestamp (epoch seconds) String data = username + timestamp; try { return CreateEncodedToken(data, secret); } catch { return null; } } private static string CreateEncodedToken(string message, string secret) { secret = secret ?? ""; var encoding = new System.Text.UTF8Encoding(); byte[] keyByte = encoding.GetBytes(secret); byte[] messageBytes = encoding.GetBytes(message); using (var hmacsha256 = new HMACSHA256(keyByte)) { byte[] hashmessage = hmacsha256.ComputeHash(messageBytes); return ByteToString(hashmessage); } } private static string ByteToString(byte[] buff) { string sbinary = ""; for (int i = 0; i < buff.Length; i++) { sbinary += buff[i].ToString("x2"); } return (sbinary); } } }
Using the snippets above for the following inputs:
Username: test_user@revinate.com
Timestamp: 1420765002
API Key: d87b88ceefbcf9d2b2adfb2bbbde1234
API Secret: b7536617fa4a1a9e3c7a707abcde866771570cb8c9a28401abcde755b48be6cb
should result in the following request headers:
X-Revinate-Porter-Username: test_user@revinate.com
X-Revinate-Porter-Timestamp: 1420765002
X-Revinate-Porter-Key: d87b88ceefbcf9d2b2adfb2bbbde1234
X-Revinate-Porter-Encoded: 753b2b64fc91ab26484d67b67eeae4f5588ce4d5b107346308a7421246c8fff8
Please contact your sales representative or account manager for your API key and API secret and appropriate access permissions.
Pagination
Some resources support pagination. Typically, these resources contain large lists for which it is impractical to return the entire result set.
When pagination is supported, the query parameters used to control the page size and page number are consistent across the API and will be page
and size
,
respectively. It is possible to specify a combination of page
and size
, which extends beyond the actual
result set – in this case, an error is not returned, however the paginated result set will be empty. Additionally, the Revinate API returns
a page
field in the response body of the form:
"page": {
"totalElements": 0,
"totalPages": 0,
"size": 0,
"number": 0
}
Where totalElements
is the total number of objects and totalPages
is the number of pages available based on the value of query param size
(default of 10 except reviews which defaults to 5. Max size is 1000).
number
is the page number of the current page.
Sorting
Some resources support sorting by fields. When sorting is supported, the query parameter used to control the sorting is consistent across the API and will be sort
.
The sort
filter is of the form {field}(,ASC|DESC)
where field
is a valid field of the resource being requested and ASC|DESC
are the available sort directions.
Default sort direction is ascending (ASC). Example: ?sort=name,DESC
.
Date Filter
Some resources support filtering by a date range. When date filtering is supported, the query parameter used to control the filtering is consistent across the API and will be date
.
The date
filter is of the form {startDate}..{endDate}
where startDate
and endDate
are epoch seconds date endpoints. Example:
1389402398..1420938399
.