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:
- Generate an API Key pair (Key, Secret, Passphrase).
- Sign each request using the HMAC SHA-256 algorithm.
- 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
Loading...