Jump to
Ctrl
+
/

Vaultody API Authentication

Vaultody REST API uses HMAC (Hash-based Message Authentication Code) to authenticate and authorize each request. You must sign every API request to ensure security and verify the integrity of communications.

This guide explains how to authenticate with Vaultody's API and includes code examples in popular programming languages.


Overview

To interact with the Vaultody API securely, you need to:

  1. Generate an API Key pair (Key, Secret, Passphrase).
  2. Sign each request using the HMAC SHA-256 algorithm.
  3. Include the required headers with every request.

Authentication Components

Required Credentials

  • API Key (x-api-key): Public identifier of your application.
  • API Secret: Used to sign your request (never shared or sent).
  • Passphrase (x-api-passphrase): Additional user-defined secret for added security.

Signature Generation

To generate the x-api-sign header:

1. Create a message string

Concatenate the following elements:

{timestamp}{HTTP_METHOD}{request_path}{body}{query_string}

Examples:

  • For GET /vaults/info?currency=BTC with no body:

    1715709672GET/vaults/info{"currency":"BTC"}
  • For POST /vaults/deposit with body:

    1715709672POST/vaults/deposit{"currency":"BTC","amount":"0.5"}

2. Decode the API secret

decoded_secret = base64.b64decode(api_secret)

3. Sign the message using HMAC SHA-256

signature = hmac.new(decoded_secret, message.encode('utf-8'), hashlib.sha256).digest()

4. Encode the signature in Base64

signature_b64 = base64.b64encode(signature).decode()

Required Headers

Header Name Description
x-api-key Your public API key
x-api-sign Base64-encoded HMAC-SHA256 signature
x-api-timestamp UNIX timestamp (in seconds)
x-api-passphrase Your passphrase
Content-Type Must be application/json

Example Usage

Python

import time, hmac, hashlib, base64, requests

api_key = 'your_key'
api_secret = 'your_secret'
passphrase = 'your_passphrase'
timestamp = str(int(time.time()))
method = 'GET'
request_path = '/vaults/info'
body = '{}'  # Empty JSON object for GET requests
query = '{}'  # Empty JSON object for query parameters

message = timestamp + method + request_path + body + query
decoded_secret = base64.b64decode(api_secret)
signature = hmac.new(decoded_secret, message.encode(), hashlib.sha256).digest()
signature_b64 = base64.b64encode(signature).decode()

headers = {
    'x-api-key': api_key,
    'x-api-sign': signature_b64,
    'x-api-timestamp': timestamp,
    'x-api-passphrase': passphrase,
    'Content-Type': 'application/json'
}

response = requests.get('https://rest.vaultody.com' + request_path, headers=headers)
print(response.json())

Node.js

const crypto = require('crypto');
const axios = require('axios');

const apiKey = 'your_key';
const apiSecret = 'your_secret';
const passphrase = 'your_passphrase';
const method = 'GET';
const requestPath = '/vaults/assets';
const body = '';
const timestamp = Math.floor(Date.now() / 1000).toString();

const message = timestamp + method + requestPath + body;
const hmac = crypto.createHmac('sha256', Buffer.from(apiSecret, 'base64'));
hmac.update(message);
const signature = hmac.digest('base64');

const headers = {
  'x-api-key': apiKey,
  'x-api-sign': signature,
  'x-api-timestamp': timestamp,
  'x-api-passphrase': passphrase,
  'Content-Type': 'application/json',
};

axios.get('https://rest.vaultody.com' + requestPath, { headers })
  .then(response => console.log(response.data))
  .catch(err => console.error(err.response.data));

POSTMAN

var CryptoJS = require("crypto-js");
const secretKey = pm.variables.get("x-api-key");
const passphrase = pm.variables.get('x-api-passphrase')
const secret = pm.variables.get('x-api-secret')
const timestamp = Math.floor(Date.now()/1000).toString();
const regex = /\n(?=(?:[^"]*"[^"]*")*[^"]*$)/g;
var reqObj = {
    method: pm.request.method.toUpperCase(),
    path: pm.request.url.getPath(),
         body: (pm.request.method === 'GET') ? JSON.stringify({}) :
         pm.request.body.raw
           .replace(regex, '')
           .replace(/(".*?")|\s+/g, '$1'),
    query: (pm.request.url.query ? pm.request.url.query : JSON.stringify({}) )
};

const transformedQueryObject = reqObj.query.reduce((result, item) => {
    result[item.key] = item.value;
    return result;
}, {});
var messageToSign = timestamp + reqObj.method + reqObj.path + reqObj.body + JSON.stringify(transformedQueryObject);
// Decoding the Base64 secret
const key = CryptoJS.enc.Base64.parse(secret);
// Creating a SHA-256 HMAC with the secret key
const hmac = CryptoJS.HmacSHA256(messageToSign, key);
// Base64 encoding the result
const signature = CryptoJS.enc.Base64.stringify(hmac);
pm.request.headers.add({
    key: "x-api-timestamp",
    value: timestamp
});
pm.request.headers.add({
    key: "x-api-sign",
    value: signature
});
pm.request.headers.add({
    key: "x-api-key",
    value: secretKey.toString()
});
pm.request.headers.add({
    key: "x-api-passphrase",
    value: passphrase
});
pm.request.headers.add({
    key: "Content-Type",
    value: 'application/json'
});

Security Best Practices

  • Keep your API keys and secrets confidential.
  • Use IP whitelisting where applicable.
  • Regularly rotate keys.
  • Limit API key permissions to necessary scopes.

Troubleshooting

Error Code Description Solution
401 Unauthorized / Invalid Signature Check timestamp, body encoding, or secret
403 Forbidden Verify API key permissions
400 Bad Request Inspect formatting and request body
Was this page helpful?
Yes
No
Powered by