Authentication
You'll need to authenticate your requests to access any of the endpoints in the Fystack API. In this guide, we'll look at how authentication works. Fystack uses HMAC-based authentication to securely verify the authenticity of your API requests.
HMAC Authentication
Fystack API uses a secure HMAC-based authentication system that requires you to sign your requests with your API secret. Each request needs three authentication headers:
Required authentication headers
ACCESS-API-KEY: your_api_key
ACCESS-TIMESTAMP: current_unix_timestamp
ACCESS-SIGN: base64_encoded_hmac_signature
The HMAC signature is generated by combining the HTTP method, request path, timestamp, and request body (if applicable), then signing it with your API secret.
Example Request with Authentication Headers
Here's an example of how to make an authenticated request to the Fystack API:
Example authenticated request
curl https://api.fystack.io/api/v1/wallets \
-H "ACCESS-API-KEY: your_api_key" \
-H "ACCESS-TIMESTAMP: 1667836889" \
-H "ACCESS-SIGN: YourBase64EncodedSignature=="
Computing the ACCESS-SIGN
To compute the HMAC signature, you'll need to:
- Create a canonical string from request parameters in fixed order:
method,path,timestamp,body - Sign this string with your API secret using HMAC-SHA256
- Hex-encode the HMAC digest, then base64-encode the hex string
Here's how to compute the signature in JavaScript:
Computing the HMAC signature
const crypto = require('crypto');
function computeSignature(apiSecret, method, path, timestamp, body = '') {
// Build canonical string in exact order
const canonical = `method=${method}&path=${path}×tamp=${timestamp}&body=${body}`;
// HMAC-SHA256 -> hex -> base64
const hexDigest = crypto.createHmac('sha256', apiSecret)
.update(canonical)
.digest('hex');
return Buffer.from(hexDigest).toString('base64');
}
// Example for GET request
const timestamp = Math.floor(Date.now() / 1000).toString();
const signature = computeSignature(
'your_api_secret', 'GET',
'/api/v1/workspaces/your_workspace_id/wallets',
timestamp
);
console.log('GET Request Headers:');
console.log('ACCESS-API-KEY:', 'your_api_key');
console.log('ACCESS-TIMESTAMP:', timestamp);
console.log('ACCESS-SIGN:', signature);
// Example for POST request with a body
const postBody = JSON.stringify({
name: "My New Wallet",
wallet_type: "mpc"
});
const postSignature = computeSignature(
'your_api_secret', 'POST',
'/api/v1/workspaces/your_workspace_id/wallets',
timestamp, postBody
);
console.log('\nPOST Request Headers:');
console.log('ACCESS-API-KEY:', 'your_api_key');
console.log('ACCESS-TIMESTAMP:', timestamp);
console.log('ACCESS-SIGN:', postSignature);
Always keep your API secret safe and reset it if you suspect it has been compromised.
Computing signatures
import CryptoJS from 'crypto-js'
function computeSignature(
apiSecret: string,
method: string,
path: string,
timestamp: string,
body: string = ''
): string {
// Build canonical string in exact order
const canonical = `method=${method}&path=${path}×tamp=${timestamp}&body=${body}`
// HMAC-SHA256 -> hex -> base64
const hexDigest = CryptoJS.HmacSHA256(canonical, apiSecret)
.toString(CryptoJS.enc.Hex)
return btoa(hexDigest)
}
// Example usage
const timestamp = Math.floor(Date.now() / 1000).toString()
const signature = computeSignature(
'your_api_secret', 'GET',
'/api/v1/workspaces/your_workspace_id/wallets',
timestamp
)
const headers = {
'ACCESS-API-KEY': 'your_api_key',
'ACCESS-TIMESTAMP': timestamp,
'ACCESS-SIGN': signature
}
Request signing process
-
Build the canonical string in fixed order:
method={METHOD}&path={PATH}×tamp={TIMESTAMP}&body={BODY}method: HTTP method in uppercase (GET, POST, etc.)path: Request path (e.g./api/v1/workspaces/{id}/wallets)timestamp: UNIX timestamp in secondsbody: JSON-stringified request body, or empty string for GET requests
-
Create the HMAC-SHA256 signature:
- Sign the canonical string with your API secret
- Hex-encode the digest
- Base64-encode the hex string
-
Add required headers:
ACCESS-API-KEY: Your API keyACCESS-TIMESTAMP: The timestamp used in the signatureACCESS-SIGN: The base64-encoded signature
Keep your API secret secure and never share it. The API key can be shared but the secret should remain private.