Authentication API v1

Authentication API is used for authenticating to the Enviso platform.

Once an API key has been created and assigned to a tenant, the integrator will be able to make use of this API key to call the API endpoints.

For each call used, you must add the headers for:

  • TenantKey: x-tenantsecretkey

  • Api key: x-api-key

  • JWT Access bearer Token: Authorization

Each key will be used for its own purpose.

  • TenantKey: Identifies the tenant for which an API action will be performed.

  • API key: Identifies the integrator which is calling the API.

  • JWT Access bearer token: Serves as authorization and authentication token in order to perform an action on the API.

How to obtain a Tenant Key (x-tenantsecretkey)

Each tenant is assigned a unique Tenant key during the Enviso registration process.

  • Resellers can obtain the Tenant key from Trade for Resellers > Settings > Connection.

  • Venue users need to contact Vintia support to obtain the Tenant key.

  • Locker site users can email Vintia support at support@gantner.com to obtain the Tenant key.

How to obtain an API Key (x-api-key)

Each tenant can get an API key and an API secret from Vintia after completing the registration process in Enviso.

Contact Vintia support via the Service desk to retrieve your API key if you want to start integrating one or more Enviso APIs.

Note

For eLoxx APIs, contact interfaces@gantner.com and share your organization name in order to obtain the API key and API secret key. The API secret key must be kept confidential.

eLoxx will never ask for your API secret. If you forget your API key and/or API secret key, contact interfaces@gantner.com

The API Key is public and should be transferred during each request in the API communication. It can be transferred in plain text without compromises.

The API Secret is private, can only be downloaded once, and is not retrievable afterward. The API Secret must never be transferred from tenant to Enviso as this would compromise the application security!

Caution

The API secret key must be kept confidential and Enviso will never ask for your API secret key. If your API secret key is lost or compromised, it is recommended to request a new combination of API key and API secret key to Vintia support via the Service desk.

Important to know:

  • In case you have multiple Venue units, you will need to obtain the Tenant key, API key, and API secret key for each Venue unit.

  • When logged into a Venue unit, you will not be able to fetch information or register sales for other Venue units.

How to obtain a JWT Access bearer token (Authorization)

Obtaining a JWT access bearer token using an API key is done by calling the Login endpoint on the Authentication API.

This login action will provide you with a Token and a Refresh token. The JWT Access bearer token will be used for the Enviso APIs for authentication and no further calls will be required for the Authentication API.

The JWT Access bearer token is valid for 1 hour, afterwards, a new token can be retrieved by extending the current token or requesting a new token.

The JWT Refresh bearer token is valid for 30 days, afterwards, a new login is required to retrieve a new duo of tokens.

To learn about JWT access bearer tokens, visit https://jwt.io/

Log in with your API Key

Procedure:
  1. Concatenate the API key with the current timestamp in the format below: <<APIKEY>>_<<timestamp(yyyy'-'MM'-'ddTHH:mm:ss.fffZ)>>

  2. Create a SHA256 hash of this value. Based on the hashed value, a digital signature will be created.

  3. The combination of the created signature along with the provided API secret key will act as the digital signature of the call.

  4. Send these values to the login action.

  5. After successful validation, a JWT Access bearer token will be provided.

The validity of the JWT token is 1 hour. The parameter refreshToken allows you to extend the session by renewing the JWT token from the server-side before the existing token expires.

To make this process easier, a sample application is created which can be used to validate if the created signature is correct. It is also available on https://github.com/gantner-nv/EnvisoApiAuthentication

Example:

Assuming we have the following data

API key

QrCDN6CcXkGOnRiNcZMrpw==

API secret

-----BEGIN PUBLIC KEY-----

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCgBSU90PX4WyXFAZ/+M84dJNEi /0j5OermfydTU4g2JvnpO6BOQjNpb5+mOLjVoij7DWTdDtx1WThRm04N3DVuyh+a 5cledvMbcngvyiXpQCdskT9bVmI4QLbmRny46S7MER1jhziMQRfRw9gbmlB2iCEq n21kDr842Q+WDtLE4QIDAQAB

-----END PUBLIC KEY-----

TimeStamp

2018-01-22T13:58:33.871Z

The hashed value of step 2 will be:

9952375a30708b46739986482303cae30ad51fc9a362b5794d298dfc22f7ec02

The signature of step 3 will be:

iMTchrTU9pMWFDRYQNCnUiD2ekDdCgp0ybN7xzvj9DLtceTFsF/kxzr9q5OnqP0quyt7OGBZ/vEQlOKhODxK2wsAml/v9Rm9Ha/CVTbQ2jVWxUH3HyDqDSRQBfYPlA79vxP2CcFEB1DbNla9TlBAwovSJVy9D0oURPoe8XrJqog=

The values to post to the login action will be:

{ "apikey": "QrCDN6CcXkGOnRiNcZMrpw==", "timestamp": "2018-01-22T13:58:33.871Z", "signature": "iMTchrTU9pMWFDRYQNCnUiD2ekDdCgp0ybN7xzvj9DLtceTFsF/kxzr9q5OnqP0quyt7OGBZ/vEQlOKhODxK2wsAml/v9Rm9Ha/CVTbQ2jVWxUH3HyDqDSRQBfYPlA79vxP2CcFEB1DbNla9TlBAwovSJVy9D0oURPoe8XrJqog=" }

Note

A sample application is available on GitHub which can be used to validate if the correct signature is created on https://github.com/gantner-nv/EnvisoApiAuthentication

Warning

The error Api key authentication failed. indicates that something is wrong with the request payload that was sent.

This can have multiple causes, but here's an overview of the most common causes:

  • Wrong API key: Ensure the API key is sent both in the request header ("x-api-key") and in the request payload ("apiKey").

  • Invalid signature: Ensure the create signature procedure is implemented correctly and the value is passed in the request body "signature" field.

  • Invalid timestamp: A validation mechanism verifies that the timestamp is still a current/valid timestamp to prevent old payloads from being used.

    In short, we validate if the timestamp sent in the request payload is within the range of our server timestamp with an allowed clock drift of 2 minutes both in the past and future.

    So make sure the machine you are running on has the clock set correctly and that you are using your payloads within the allotted time.

Send values to the Login action.

Login

POST /{version}/login

x-api-key: QrCDN6CcXkGOnRiNcZMrpw==

Host:

  • For Direct selling API: https://api.staging-enviso.io/directsellingapi

  • For Reselling API: https://api.staging-enviso.io/resellingapi

  • For Payment API: https://api.staging-enviso.io/paymentapi

  • For Scanning API:https://api.staging-enviso.io/scanningapi

  • For eLoxx API:https://api.staging-enviso.io/eloxxapi

Content-Type: application/json

Cache-Control: no-cache

{ "apikey": "QrCDN6CcXkGOnRiNcZMrpw==", "timestamp": "2018-01-22T13:58:33.871Z", "signature": "iMTchrTU9pMWFDRYQNCnUiD2ekDdCgp0ybN7xzvj9DLtceTFsF/kxzr9q5OnqP0quyt7OGBZ/vEQlOKhODxK2wsAml/v9Rm9Ha/CVTbQ2jVWxUH3HyDqDSRQBfYPlA79vxP2CcFEB1DbNla9TlBAwovSJVy9D0oURPoe8XrJqog=" }

How to make further calls using API key

Once the JWT token is obtained, it must be sent along with each request together with the API key to get access to the actions of the API.

Example:

GET /v1/offers

Host: localhost:5051

x-tenantsecretkey: TadeHm6PjEig8gUAewcgsg/==

x-api-key: QrCDN6CcXkGOnRiNcZMrpw==

Authorization: bearer SPACE <JWT-access token>

Content-Type: application/json

Following diagram shows the communication flow for authenticating to Enviso with your API key:

ATHAPI_clip0001.png

Going live

When going live from the staging environment to the production environment:

  • Use the production environment API Key and Tenant key of the Authentication API.

    Note

    Contact Vintia support to get your production environment keys of the Authentication API.

  • Change the base URL from the staging environment to the production environment.

    • Production environment: https://api.enviso.io/authenticationapi

    • Staging environment: https://api.staging-enviso.io/authenticationapi

Log in

Request body

Responses

Success response code: 200 OK

Error response codes

Code

Description

400

Bad Request

401

Unauthorized

422

Unprocessable Entity

500

Internal Server Error

Request
var client = new RestClient("https://api.staging-enviso.io/authenticationapi/v1/login");
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("origin", "string");
request.AddHeader("x-api-key", "API_KEY");
request.AddParameter("application/json", "{\"apiKey\":\"string\",\"timestamp\":\"2019-08-24T14:15:22Z\",\"signature\":\"string\"}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Request
HttpResponse<String> response = Unirest.post("https://api.staging-enviso.io/authenticationapi/v1/login")
  .header("Content-Type", "application/json")
  .header("origin", "string")
  .header("x-api-key", "API_KEY")
  .body("{\"apiKey\":\"string\",\"timestamp\":\"2019-08-24T14:15:22Z\",\"signature\":\"string\"}")
  .asString();
Request
const data = "{\"apiKey\":\"string\",\"timestamp\":\"2019-08-24T14:15:22Z\",\"signature\":\"string\"}";

const xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://api.staging-enviso.io/authenticationapi/v1/login");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("origin", "string");
xhr.setRequestHeader("x-api-key", "API_KEY");

xhr.send(data);
Request
import http.client

conn = http.client.HTTPSConnection("api.staging-enviso.io")

payload = "{\"apiKey\":\"string\",\"timestamp\":\"2019-08-24T14:15:22Z\",\"signature\":\"string\"}"

headers = {
    'Content-Type': "application/json",
    'origin': "string",
    'x-api-key': "API_KEY"
    }

conn.request("POST", "/v1/login", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
{
	"apikey": "string",
	"timestamp": "date", // UTC+00:00 format (eg. 2018-12-05T15:48:49.847Z) 
	"signature": "string"
}
Response
{
	"authToken": "string",
	"refreshToken": "string"
}
json
{
   "errors": [
      {
         "message": "string",
         "code": 0
      }
   ]
}

Renew token

Request body

Responses

Success response code: 200 OK

Error response codes

Code

Description

400

Bad Request

401

Unauthorized

404

Not Found

422

Unprocessable Entity

500

Internal Server Error

Request
var client = new RestClient("https://api.staging-enviso.io/authenticationapi/v1/renew");
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Authorization", "string");
request.AddHeader("origin", "string");
request.AddHeader("x-api-key", "API_KEY");
request.AddParameter("application/json", "{\"refreshToken\":\"string\"}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Request
HttpResponse<String> response = Unirest.post("https://api.staging-enviso.io/authenticationapi/v1/renew")
  .header("Content-Type", "application/json")
  .header("Authorization", "string")
  .header("origin", "string")
  .header("x-api-key", "API_KEY")
  .body("{\"refreshToken\":\"string\"}")
  .asString();
Request
const data = "{\"refreshToken\":\"string\"}";

const xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://api.staging-enviso.io/v1/renew");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("Authorization", "string");
xhr.setRequestHeader("origin", "string");
xhr.setRequestHeader("x-api-key", "API_KEY");

xhr.send(data);

const inputBody = '{
  "refreshToken": "string"
}';
const headers = {
  'Content-Type':'application/json',
  'Authorization':'string',
  'origin':'string',
  'x-api-key':'API_KEY'
};

fetch('https://api.staging-enviso.io/renew',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});
Request
import http.client

conn = http.client.HTTPSConnection("api.staging-enviso.io")

payload = "{\"refreshToken\":\"string\"}"

headers = {
    'Content-Type': "application/json",
    'Authorization': "string",
    'origin': "string",
    'x-api-key': "API_KEY"
    }

conn.request("POST", "/v1/renew", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
{
	"refreshToken": "string"
}
Response
{
   "token": "string"
}
{
   "errors": [
      {
         "message": "string",
         "code": 0
      }
   ]
}

Obtain visitor token

Request body

{
  "externalJwt": "string"
}

Responses

Success response code: 200 OK

Error response codes

Code

Description

400

Bad Request

401

Unauthorized

404

Not Found

422

Unprocessable Entity

500

Internal Server Error

Request
var client = new RestClient("https://api.staging-enviso.io/authenticationapi/v1/visitor/exchange-token");
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Authorization", "string");
request.AddHeader("origin", "string");
request.AddHeader("x-api-key", "API_KEY");
request.AddParameter("application/json", "{\"externalJwt\":\"string\"}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Request
HttpResponse<String> response = Unirest.post("https://api.staging-enviso.io/authenticationapi/v1/visitor/exchange-token")
  .header("Content-Type", "application/json")
  .header("Authorization", "string")
  .header("origin", "string")
  .header("x-api-key", "API_KEY")
  .body("{\"externalJwt\":\"string\"}")
  .asString();
Request
const data = "{\"externalJwt\":\"string\"}";

const xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://api.staging-enviso.io/authenticationapi/v1/visitor/exchange-token");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("Authorization", "string");
xhr.setRequestHeader("origin", "string");
xhr.setRequestHeader("x-api-key", "API_KEY");

xhr.send(data);
Request
import http.client

conn = http.client.HTTPSConnection("api.staging-enviso.io")

payload = "{\"externalJwt\":\"string\"}"

headers = {
    'Content-Type': "application/json",
    'Authorization': "string",
    'origin': "string",
    'x-api-key': "API_KEY"
    }

conn.request("POST", "/v1/visitor/exchange-token", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
Response
{
	"token": "string",
}
json
{
	"errors": [{
		"message": "string",
		"code": "number"
	}]
}