Issues with pritunl api - 401 - Unauthorized

I am using two pritunl vpn server in enterprise version, one for sandbox env, second for production and development. Both VM are hosted on AWS. Same code is being used for api calls on sbox and prod. Ofcourse with different api tokens and api secrets.
The issue is that on production server i am getting 401 error unathorized even if i generate multiple times new token and secret. Same code for sbox is working without any problems.

import json
import os
import re
import sys
import requests
import time
import uuid
import hmac
import hashlib
import base64
import json
import sys
import urllib

path = os.getcwd()
fileName = os.path.join(path, 'azure_public_ips.json')

if os.path.exists(fileName):

# Get actual working download link - it is changing during new json file is released
# eg.
webpage = ""
with urllib.request.urlopen(webpage) as response:
    rawhtml ='utf-8')
    match ='[^"]*', rawhtml)
    if match:
        download_url =
        urllib.request.urlretrieve(download_url, fileName)

with open(fileName) as f:
    contents = json.load(f)

output = []
for value in contents['values']:
    properties = value.get('properties', {})
    region = properties.get('region', '')
    service_tag = properties.get('serviceTag', '')
    systemService = properties.get('systemService')
    if systemService in ['AzureStorage']:
        address_prefixes = properties.get('addressPrefixes', [])
        for network in address_prefixes:
            output.append({'network': network, 'nat': True})

with open(os.path.join(path, 'output.json'), 'w') as f:
    json.dump(output, f)
BASE_URL = 'http://localhost'
SERVER_ID = '60e5690369a63ad764e32f71'

def auth_request(method, path, headers=None, data=None, verify=None):
    auth_timestamp = str(int(time.time()))
    print("auth_time " + auth_timestamp)
    auth_nonce = uuid.uuid4().hex
    print("auth_nonce " + auth_nonce)
    auth_string = '&'.join([API_TOKEN, auth_timestamp, auth_nonce,
        method.upper(), path])
    if sys.version_info[0] < 3:
        auth_signature = base64.b64encode(
            API_SECRET, auth_string, hashlib.sha256).digest())
        auth_signature = base64.b64encode(
            API_SECRET.encode('utf-8'), auth_string.encode('utf-8'), hashlib.sha256).digest())
    auth_headers = {
        'Auth-Token': API_TOKEN,
        'Auth-Timestamp': auth_timestamp,
        'Auth-Nonce': auth_nonce,
        'Auth-Signature': auth_signature,
    if headers:
    return getattr(requests, method.lower())(
        BASE_URL + path,

# Read routes from the output.json file created in the previous script
with open("output.json", "r") as f:
    routes = json.load(f)

for route in routes:
    json_str = json.dumps(route)
    print(f"Added route {json_str}")
    response = auth_request(
            'Content-Type': 'application/json',

    if response.status_code != 200:
        print(f"Error: {response.status_code} - {response.reason}")

The server doesn’t log the reason for those 401 errors. It’s possible there’s an issue with the client or server time causing the timestamp to be out of the acceptable range. A common cause for date/time issues is having a client or server with the correct time but incorrect timezone. The time will appear to be accurate but when the software creates a timestamp it converts the systems local time to UTC, if the correct time is used with the incorrect timezone the conversion will return the wrong UTC time.