Using the API
Introduction
This documentation is for the newly created API for the CU Wireless product LiveSurvey. The first phase of the API rollout is focused on providing subscribers with the ability to programmatically access LiveSurvey data leveraging the reporting capability.
Endpoint types
All endpoints are POST endpoints.
Available endpoints
Identity Login
Purpose:
With the Identity Login endpoint, LiveSurvey login credentials are passed in and the SSO token is returned. This is the first step in the authentication process. The sign in email and password used here are those for an Admin-role Remote Access User. LiveSurvey recommends setting up a dedicated email (for instance, livesurveyapi@creditunion.com) for use with the API and storing the credentials securely. Any user with an Admin role can access all survey data.
URL:
https://login.livecusurvey.com
Route:
POST api/login
Post:
{
"Email": "EMAIL",
"Password": "PASSWORD"
}
Example:
{
"Email": "john.doe@bigcreditunion.com",
"Password": "abc123!321CBA"
}
Return:
Success = 200 (OK) - The response from LiveSurvey will return a LiveSurvey SSO token.
{
"ssoToken": "SSO_TOKEN"
}
Error = 401 - Login credentials are not valid.
Portal Login
Purpose:
The Portal Login endpoint is used to pass the SSO token returned from the Identity Login endpoint. This endpoint will return a JWT token.
Note: The JWT token expiration time is 20 minutes.
Access:
This endpoint is only available to Admin level (or higher) LiveSurvey users.
URL:
https://SUBDOMAIN.livecusurvey.com
Route:
POST api/v2/jwt/login
Post:
{
"ssoToken": "SSO_TOKEN"
}
Return:
Success = 200 (OK) - The response from LiveSurvey will return a JWT token.
{
"token": "JWT_TOKEN"
}
Error = 401 - SSO token is not supplied or not valid.
Error = 404 - URI subdomain is incorrect. No client is not found at the provided subdomain.
Generate Report
Purpose:
The Generate Report endpoint submits a request to LiveSurvey to run (generate) the specified report.
Note about date ranges: The report results will be inclusive of data from the specified end date.
Route:
POST api/v2/jwt/report
Post:
{
"token": "JWT_TOKEN",
"type": "REPORT_TYPE", // (Export, Summary, Departments, Employees, Comments, Transaction, NetPromoter)
"surveyId": SURVEY_ID,
"start": "yyyy-MM-dd", // Report Start Date
"end": "yyyy-MM-dd" // Report End Date
}
Example:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOiI5NiIsIlVzZXJuYW1lIjoic3VwZXIyIiwiTmFtZSI6IiIsIkVtYWlsIjoiIiwiVGl0bGUiOiIiLCJEZXBhcnRtZW50S2V5IjoiIiwiRW1wbG95ZWVLZXkiOiJzdXBlcjIiLCJDbGllbnRHcm91cElkIjoiIiwiQ2xpZW50R3JvdXBOYW1lIjoiIiwiQ2xpZW50SWQiOiIzIiwiQ2xpZW50TmFtZSI6IiIsIkNsaWVudFRhZ3NFbmFibGVkIjoiVHJ1ZSIsIlJvbGUiOiJTdXBlciIsIlN1YmRvbWFpbiI6InN0YWdpbmciLCJUaW1lWm9uZUlkIjoiUGFjaWZpYyBTdGFuZGFyZCBUaW1lIiwibmJmIjoxNjMwNDQyMzM2LCJleHAiOjE2MzA0NDM1MzYsImlhdCI6MTYzMDQ0MjMzNn0.BH4jRU9h1-yKlZsyqMnsKcnZFWY1sO-duzByocfxqB8",
"type": "Transaction",
"surveyId": 3,
"start": "2021-07-01",
"end": "2021-07-31"
}
Return:
Success = 201 - A 201 response from LiveSurvey confirms that the requested report was submitted successfully to the Report Job queue to be created.
Error = 400 - Report Type, Survey ID, Start Date or End Date is not valid.
Error = 401 - The token is not valid.
Report List
Purpose:
The Report List endpoint will return an array of the previously generated reports associated with the user’s ClientID. The reports will be sorted by date, starting with the most recently generated.
Route:
POST api/v2/jwt/report/list
Post:
{
"token": "JWT_TOKEN",
"max": NUMBER_OF_REPORTS // default is 1
}
Example:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOiI5NiIsIlVzZXJuYW1lIjoic3VwZXIyIiwiTmFtZSI6IiIsIkVtYWlsIjoiIiwiVGl0bGUiOiIiLCJEZXBhcnRtZW50S2V5IjoiIiwiRW1wbG95ZWVLZXkiOiJzdXBlcjIiLCJDbGllbnRHcm91cElkIjoiIiwiQ2xpZW50R3JvdXBOYW1lIjoiIiwiQ2xpZW50SWQiOiIzIiwiQ2xpZW50TmFtZSI6IiIsIkNsaWVudFRhZ3NFbmFibGVkIjoiVHJ1ZSIsIlJvbGUiOiJTdXBlciIsIlN1YmRvbWFpbiI6InN0YWdpbmciLCJUaW1lWm9uZUlkIjoiUGFjaWZpYyBTdGFuZGFyZCBUaW1lIiwibmJmIjoxNjMwNDQyMzM2LCJleHAiOjE2MzA0NDM1MzYsImlhdCI6MTYzMDQ0MjMzNn0.BH4jRU9h1-yKlZsyqMnsKcnZFWY1sO-duzByocfxqB8",
"max": 1
}
Return:
Success = 200 (OK) - The response from LiveSurvey will be an array of available reports.
{
"reports": [
{
"ReportId": REPORT_ID,
"Type": "REPORT_TYPE", // (Export, Summary, Departments, Employees, Comments, Transaction, NetPromoter)
"SurveyId": SURVEY_ID,
"Start": "yyyy-MM-dd", // Report Start Date
"End": "yyyy-MM-dd", // Report End Date
"Timestamp": "CREATED_ON_DATE_TIME"
}
]
}
Error = 400 - There is an issue with the report service.
Error = 401 - The token is not valid.
Report Download
Purpose:
The Report Download endpoint will return the requested report file as an XLSX file.
Route:
POST api/v2/jwt/report/download
Post:
{
"token": "JWT_TOKEN",
"ReportId": REPORT_ID
}
Example:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOiI5NiIsIlVzZXJuYW1lIjoic3VwZXIyIiwiTmFtZSI6IiIsIkVtYWlsIjoiIiwiVGl0bGUiOiIiLCJEZXBhcnRtZW50S2V5IjoiIiwiRW1wbG95ZWVLZXkiOiJzdXBlcjIiLCJDbGllbnRHcm91cElkIjoiIiwiQ2xpZW50R3JvdXBOYW1lIjoiIiwiQ2xpZW50SWQiOiIzIiwiQ2xpZW50TmFtZSI6IiIsIkNsaWVudFRhZ3NFbmFibGVkIjoiVHJ1ZSIsIlJvbGUiOiJTdXBlciIsIlN1YmRvbWFpbiI6InN0YWdpbmciLCJUaW1lWm9uZUlkIjoiUGFjaWZpYyBTdGFuZGFyZCBUaW1lIiwibmJmIjoxNjMwNDQyMzM2LCJleHAiOjE2MzA0NDM1MzYsImlhdCI6MTYzMDQ0MjMzNn0.BH4jRU9h1-yKlZsyqMnsKcnZFWY1sO-duzByocfxqB8",
"ReportId": 11
}
Return:
Success = 200 (OK) - The response from LiveSurvey will return the specified report (XLSX) file.
Error = 400 - The Report ID is empty.
Error = 401 - The token is not valid.
Error = 404 - The report service cannot find the specified report.
Code Example
The following code example is written in Python and was tested using Python 3.9.2.
This Python script demonstrates the entire flow:
- Logs in using your Identity credentials to retrieve an SSO token
- Uses the SSO token to retrieve a JWT login
- Submits a report to be generated
- Waits 30s for the report to be generated
- Gets a list of the last 3 reports created
- Downloads the most recent report
Copy and paste the code into a new Python file. Update the creds and settings at the top to match your account and report info. Once everything is updated correctly, running the Python script should download the report file into the same folder as the script file. The report file will be named using the report info.
'''LiveSurvey Report API example'''
import requests
import time
# creds, settings
API_HOST = 'https://SUBDOMAIN.livecusurvey.com' # update with your subdomain
EMAIL = 'LOGIN_EMAIL' # update with your admin login email
PASSWORD = 'LOGIN_PASSWORD' # update with your admin login password
REPORT_TYPE = 'Export' # update with your report type
REPORT_SURVEY_ID = 1 # update with your report survey id
REPORT_START = '2021-08-01' # update with your report start date
REPORT_END = '2021-08-31' # update with your report end date
WAIT_TIME = 30 # wait time in seconds for report to generate
REPORT_LIST_MAX = 3 # maximum reports returned
#########################################
# Identity login
#########################################
def get_sso_token(email, password):
'''Returns an SSO token after authenticating login credentials.'''
url = 'https://login.livecusurvey.com/api/login'
payload = {
'Email': email,
'Password': password
}
response = requests.post(url=url, json=payload)
sso_token = response.json().get('ssoToken')
print('- ...received SSO token: %s' % sso_token)
return sso_token
#########################################
# Portal login
#########################################
def get_jwt_token(ssoToken):
'''Returns a JWT token after authenticating SSO token credentials.'''
url = '%s/api/v2/jwt/login' % API_HOST
payload = {
"ssoToken": ssoToken
}
response = requests.post(url=url, json=payload)
jwt_token = response.json().get('token')
print('- ...received JWT token %s' % jwt_token)
return jwt_token
#########################################
# Generate report
#########################################
def api_generate_report(token, type_, survey_id, start, end):
'''Submits a report to be generated.'''
url = '%s/api/v2/jwt/report' % API_HOST
payload = {
'token': token,
'type': type_,
'surveyId': survey_id,
'start': start,
'end': end,
}
response = requests.post(url=url, json=payload, stream=True)
return response
#########################################
# Report list
#########################################
def api_report_list(token, max):
'''Returns a list of the latest available reports.'''
url = "%s/api/v2/jwt/report/list" % API_HOST
payload = {
"token": token,
"max": max # defaults to 1 if absent
}
response = requests.post(url=url, json=payload)
return response.json().get('reports')
#########################################
# Report download
#########################################
def api_report_file(token, report_id):
'''Downloads the specified report.'''
url = "%s/api/v2/jwt/report/download" % API_HOST
payload = {
"token": token,
"ReportId": report_id
}
response = requests.post(url=url, json=payload, stream=True)
return response
#########################################
# Get the login tokens
#########################################
print('- Getting SSO token...')
sso_token = get_sso_token(EMAIL, PASSWORD)
print('- Getting JWT token...')
jwt_token = get_jwt_token(sso_token)
#########################################
# Submit a report
#########################################
print('- Requesting report generation...')
report_response = api_generate_report(jwt_token, REPORT_TYPE, REPORT_SURVEY_ID, REPORT_START, REPORT_END)
if (report_response.status_code == 201):
print("- ...success.")
print('- Report submitted.')
else:
print("! Failed: (%d) %s" % (report_response.status_code, report_response.text))
#########################################
# Wait for submitted report to generate
# This wait time may need to be adjusted depending on the size of the reports
#########################################
print("- ...waiting %d seconds for report to be generated." % WAIT_TIME)
time.sleep(WAIT_TIME)
#########################################
# Retrieve the report list
#########################################
print("- Getting report list:")
reports = api_report_list(jwt_token, REPORT_LIST_MAX)
for r in reports:
print("- ------")
print(" id:\t\t%s\n survey_id:\t%s\n type:\t\t%s" % (r['ReportId'], r['SurveyId'], r['Type']))
print(" start:\t%s\n end:\t\t%s" % (r['Start'], r['End']))
print(" timestamp:\t%s" % (r['Timestamp']))
print("\n- Returned %d reports; done." % len(reports))
print("\n- Latest Report ID is %d" % reports[0]['ReportId'])
#########################################
# Download the latest report
# This report should be the one submitted above
#########################################
print("- Getting report file...")
report = api_report_file(jwt_token, reports[0]['ReportId'])
filename = "report%s_survey%s_%s_%s_%s.xlsx" % (reports[0]['ReportId'], reports[0]['SurveyId'], reports[0]['Type'], reports[0]['Start'], reports[0]['End'])
print("- Writing `%s`..." % filename)
c = 0
with open(filename, "wb") as fd:
for chunk in report.iter_content():
fd.write(chunk)
c += 1
print("- Wrote %d bytes; done." % c)