1. Overview
  2. Procedures for create a service app in the staging developer portal
  3. Scopes
  4. Service account
  5. Create Service App JWT with Credentials
  6. Use the service app JWT in Spaces API requests

1 Overview

If you are creating an application that needs to perform user administration functions, an application that can create adhoc meeting rooms, or a bot application that can interact with other users, you can consider using the service type of application (service app).

The service app is designed for server-to-server communication. The service type of application utilizes the service account to access the Spaces API. The service account is a special user account under a company. It doesn’t allow login. It can be assigned with a Spaces license.

Only a Spaces user with company admin and developer permissions can create a new service app. Avaya Support personnel must create the service account domain for your company before you can create the service app.

The service app belongs to the company that is managed by the creator. It can only access the resources within this company. If your application needs to access multiple companies, you must create separate service apps for each company..

2 Procedures for creating a service app in the staging developer portal

  1. Create a free Avaya Spaces developer account in the Spaces staging environment
    • Go to https://loganstaging.esna.com/
    • Enter your work email address.
    • Click Yes, Sign me Up! (below the Sign In button).
    • You’ll receive an email from Avaya Spaces. Follow the steps to create your Avaya Spaces password.
    • Go to https://onesnastaging.esna.com. Login with your email and password if it’s not auto logged in.
    • Go to User Settings on the left-side menu. Enable the Developer Permission checkbox under the “General” tab.
  2. Create a company that matches to your work email address domain if your User Settings doesn’t have any Current Employers
    • Stay on https://onesnastaging.esna.com, in the upper-right corner drop-down menu under your name, click Add Company.
    • Enter the name of your company then click Save.
    • Click on the Domains tab, add a company domain that matches your work email domain. Then click on Verify button to on the domain you just created. The domain will be auto approved if it matches to your work email domain and you have enabled the Developer Permission.
    • Go to User Settings on the left-side menu. Enable the Developer Permission checkbox that is labelled with your company name under the “General” tab.
  3. Enable service account domain
    • Reload the https://onesnastaging.esna.com, go to Manage Companies on left-side menu then click on your company.
    • Under the Service accounts tab, click Create service domain button.
  4. Create service applications
    • Reload the https://onesnastaging.esna.com, go to Manage company apps.
    • Click Create an app, then select the Service in the Application type dropdown. Remember to select a company for the service app.

3 Scopes

After a service app is created, you must configure the service app scope. You can select multiple scope options from the following list. Each scope corresponds to an API endpoint.

API EndpointsScopesPurpose
POST /users/bulkupdateaccounts.users.bulk.writeCreate, update, or delete users in bulk
GET /companies/list_usersaccounts.company.users.listList users which have employee relation to company which owns the service app
POST /spaces/{spaceId}/chatsspaces.chat.createSend new chat messages into a space
GET /spaces/{spaceId}/messages/byrefspaces.chat.readRetrieve messages from the space where the service account is the admin or member
POST /spaces/invitespaces.createCreate a new space with service account as the owner
POST /spaces/invite with “X-Avaya-Act-As” headerspaces.create.actasCreate a new Space with another user as the owner
DELETE /spaces/{spaceId}spaces.deleteDelete the space where the service account is the admin
GET /spaces/direct/user/{userId}spaces.direct.createCreate a direct messaging space between the service account and another user
POST /spaces/{spaceId}/invitespaces.invite.writeInvite to the space where the service account is the admin
GET /users/me/spacesspaces.listList space where the service account is the admin
GET /spaces/{spaceId}spaces.settings.readGet the space's settings where the service account is the admin
POST /spaces/{spaceId}spaces.settings.writeUpdate the space's settings where the service account is the admin
Socket.IO connectionspaces.websocketConnect websocket to a space
GET /users/me/colleaguesusers.searchSearch for users within the company
POST /users/me/colleaguesbulkusers.search.bulkSearch for list of user emails within the company
GET /spaces/{spaceId}/ideasspaces.post.readRetrieve posts from the space which service account is the admin or member
POST /spaces/{spaceId}/ideasspaces.post.createCreate a new post into a space which service account is the admin or member
GET /spaces/{spaceId}/taskspaces.task.readRetrieve tasks from the space which service account is the admin or member
POST /spaces/{spaceId}/tasksspaces.task.createCreate a new task into a space which service account is the admin or member
POST /messages/{messageId}spaces.messages.writeUpdate the post and task in the space which service account is the admin or member

4 Service account

A new service account is automatically created for each new service application. If the service account is disabled by the company admin, the associated service application cannot access the Spaces API anymore.

If your service application needs to create new spaces for meeting, you should assign a Spaces Power or Business license to the service account so that the created spaces can support the meeting features that come with the license bundle.

5 Create Service App JWT with Credentials

To create the service app JWT, use the following procedure:

  1. Activate the service app.
  2. Add a new public/private key pair under the Credentials tab.
  3. Click on the Download Key button.
    • Note: The downloaded file service-key-f14f61d7f84347880427.json contains the private key information needed to create the JWT. After using it in your code, delete the file as soon as possible. You can download it again or generate a new one if needed. For your protection, treat the file as a password and do not share it.
  4. Create the JWT using the data from the downloaded json file and sign it using the private key included in the file.

The following is an example of the downloaded service-key-f14f61d7f84347880427.json file:

{
  "iss": "66862e5f427b7cf325db", 
  "sub": "66862e5f427b7cf325db@psrsu9.servicesapps.spaces.avayacloud.com", 
  "kid": "f14f61d7f84347880427", 
  "private_key": "-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAzA/6J6IiJIH4e1HXFLdvw/YTeSvIjzzTkFyWeNtDDoC8fhhs
h56HkwRvX4CnEsB+ebiyQPf3bvvnqzVcJPVaei2mXbEaROpqaNEnRHWhEV3PcHFY
nEPbThYddEU9BmupSoxpESZU5R0GfaWfmGypZxbBhI2TkELE36t4ictIO86ajVSd\nhaAc32djbOUYvkEi9w3/o0fMPKY//z6DSTl92Cu09nnoZtAWnU3lL4HnTXYxv7
/he1evxAqIi4kvK+DcguHgOMPNzWepltqFu98M06dNx+joeuWjMtq0K7y2QHSk01
Y2aGHVOv8hNx9cgtYoSiBz2JWT1ZQ+TG3K+AM50CgYARQ/tqHBnaXD1vE1rueVG3
Xk6Mp8lab1znpdsgeTHkB7nKzoMEkoQxBytW+dh8/3nxfPQwgOozJJ1sAIja772B
IW10xTglL2f1lH7+5BgqLiGyf4bh7zKmW3xDC3gCekJrT4BrHc9lkEyCUJgj0tbz
9CndCLR70ymT6neMoe0VZQKBgGrrRYnKod5WNuYkmmvlMlvZFRu3tPt9tsrShC9a
+9GO2qpR1l5HcOJ3+y0XUzIA/Y+eBjU2GhtjWLS38Szjx7k526RvbVDFfMZR1dRz
UXkfwAQBw2wPLms0XMwudjPK/c4cgtTBEcuNCG4uN+2SBvr6/TOeXfkuO5DPkdcC
ztWRAoGAHN7cLV4ORtcdEIs4GAm0hgejIhNX7gaES0hR1h2C3gwKsvPPAkFkaiqs
fBv7sJKn0fZ7AVRYfUwJTvFDpVyrtuIFzy7jMTezDm6mKqBeK0C3R6AAsPubKqeS
WBoAlIdaQM5iOCuxtRe6YlpEUPMJfgtPVn/iTw+U2DdpuUrBzi0=
-----END RSA PRIVATE KEY-----"
}

The following is an example of the service app JWT, which you can create based on the downloaded JSON:

header:

{
  "typ": "JWT",
  "alg": "RS256",
  "kid": "f14f61d7f84347880427"
}

payload:

{
"iss": " 66862e5f427b7cf325db",
"sub": " 66862e5f427b7cf325db@psrsu9.servicesapps.spaces.avayacloud.com",
"aud": "spaces.avayacloud.com",
"exp": 2631806787
}

The exp is the JWT expiry time. The maximum exp time you can set is 3600 seconds for security reasons. The JWT token will be rejected by Spaces server if the exp time is greater than 3600 seconds. The exp time should be in the Unix timestamp format. For testing, you can manually generate the exp time value using online tools such as https://www.unixtimestamp.com/.

After creating the exp value, you can sign the JWT with the private key included in the downloaded JSON file. For testing, you can use online tools such as https://dinochiesa.github.io/jwt/ to generate and sign the JWT token.

You can use any suitable library for your preferrable programming language to generate and sign JWT token programmatically https://jwt.io/libraries

For example using Node.js and 'jsonwebtoken' library

import jwt from 'jsonwebtoken';
let config = require('./service-key-f14f61d7f84347880427.json');
const {iss, sub, private_key, kid, aud} = config;
let service_acc_token = "service_app " + jwt.sign({}, private_key, {
    algorithm: 'RS256',
    issuer: iss,
    subject: sub,
    keyid: kid,
    audience: aud,
    expiresIn: '120s'
});

6 Use the service app JWT in Spaces API requests

The service app JWT is used in the Authorization header of the REST request. For example, To create a new space, you can call POST /spaces/invite with Authorization header as service_app [JWT]:

Request URL:

For Production: POST https://spacesapis.avayacloud.com/api/spaces/invite
For Staging: POST https://loganstagingapis.esna.com/api/spaces/invite

Headers:

Authorization: "service_app eyJ0eXAiOiJ1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImYxNDk0Yzc22FkODA0YjFjMGFkZTc1NyIsInN1YiI6IjA2MzNjYWQ4MDRiMWMwYWRlNzU3QGt4amE1by5zZXJ2aWNlc2FwcHMuc3BhY2VzLmF2YXlhY2xvdWQuY29tIiwiYXVkIjoic3BhY2VzLmF2YXlhY2xvdWQuY29tIiwiZXhwIjoxNjMxNzE1NTkwfQ.yEaVQ_WptwBQGqBPZN8OzP4sZC_QKgcmgPhOvZjYeRJfErXMpVpoNN9XrRsGzNCKw0Wxkd6y8jerlzPO4aY3SQL2Q0zvz2LvsOznatOULbPoRWwoABxfmJxPBGtvlSfU1hfbUjoGx8FafpShMptTeTsfh8k3Y2rqIRI3arAkjxfh3OP-PoZsuOdPswFLTZQ9jXR3w3ZeiE2xi5zlIkEziAMjTTYdldwCAvAP4JmdU_DOW2ICJlMcPL_gbjUj4Be-95CQbpQSgW1BIWs5_YPse5RupUbQ"

Here is an example how to use POST /spaces/{spaceId}/chats Spaces API endpoint programmatically using Node.js and service_app JWT

For Production:

let service_acc_token = "service_app <JWT token>";
let bodyText = "Sample Message with Service Account Authorization";
let message_request =  {
  method: 'POST',
  url: "https://spacesapis.avayacloud.com/api/spaces/{spaceId}/chats",
  headers: {
    'Authorization': service_acc_token,
    'Content-Type': "application/json"
  },
  data: { "content": {
    "bodyText": bodyText
    } },
  httpsAgent: new https.Agent({ rejectUnauthorized: false }),
};
try {
  response = await axios.default(message_request);
  console.log('Received Response: ' + response.status);
}
catch (error) {
  if(error.response != undefined){
    response.status = error.response.status;
    response.message = error.message;
    response.data = error.response.data;
  }
console.log('Encountered an error: ' + error);
return response;
}

For Staging:

let service_acc_token = "service_app <JWT token>";
let bodyText = "Sample Message with Service Account Authorization";
let message_request =  {
  method: 'POST',
  url: "https://loganstagingapis.esna.com/api/spaces/{spaceId}/chats",
  headers: {
    'Authorization': service_acc_token,
    'Content-Type': "application/json"
  },
  data: { "content": {
    "bodyText": bodyText
    } },
  httpsAgent: new https.Agent({ rejectUnauthorized: false }),
};
try {
  response = await axios.default(message_request);
  console.log('Received Response: ' + response.status);
}
catch (error) {
  if(error.response != undefined){
    response.status = error.response.status;
    response.message = error.message;
    response.data = error.response.data;
  }
console.log('Encountered an error: ' + error);
return response;
}