Skip to content
>
Mode: standard

Generate API Signature

HMAC-SHA256 · Base64

Sign every request.

The API signature is a Base64-encoded HMAC over a canonical request string, keyed with your integration's client secret. It proves both who you are and that the request hasn't been tampered with in transit.

Prerequisites

You'll need these
1
A CoinPayments API integration
Create one on the dashboard to receive your client credentials.
2
Integration clientId
Sent as the X-CoinPayments-Client header and folded into the signed string.
3
Integration clientSecret
Used only as the HMAC key — never transmitted with the request itself.

Build the Signature

4 steps
Step 1Construct the unique request

Concatenate these six elements in order — no separators — to form the message that will be signed:

  • 1BOM\ufeff
  • 2MethodPOST | GET | …
  • 3URLhttps://a-api.coinpayments.net/api/v2/…
  • 4Client IDclientId
  • 5TimestampYYYY-MM-DDTHH:mm:ss
  • 6Payload{ "key": "value" }
Step 2Hash the message

Compute an HMAC over the concatenated string using SHA-256 with your clientSecret as the key.

Step 3Encode the hash

Encode the resulting digest in Base64. The signature is the final Base64 string.

Step 4Set the X-CoinPayments-Signature header

Send the Base64 value as the X-CoinPayments-Signature header alongside the other two required headers.

Worked Example

Node.js

A complete example showing how to construct the message, sign it, and send the request. The highlighted lines are the signature-specific portion — wrap them in a helper and reuse across your codebase, or use our SDK.

Node.js
import { createHmac } from 'node:crypto';
import axios from 'axios';
 
// Pull sensitive data from environment.
const integration = {
	clientId: process.env.INTEGRATION_CLIENT_ID,
	clientSecret: process.env.CLIENT_SECRET
};
 
// Retrieve the current date in UTC ISO-8601 format 
// format YYYY-MM-DDTHH:mm:ss (excluding milliseconds and timezone) 
const isoDate = new Date().toISOString().split('.')[0]; // i.e. 2025-03-01T02:30:00 
 
// Define request method, URL, and payload. 
const request = { 
	method:'POST', 
	url: 'https://a-api.coinpayments.net/api/v1/merchant/wallets', 
	data: { 
		currencyId: 2,
		label: 'Online Shop Wallet',
		webhookUrl: 'https://api.my-store.com/webhooks/endpoint',
	}, // or null 
	headers: { 
		'X-CoinPayments-Client': integration.clientId, 
		'X-CoinPayments-Timestamp': isoDate, 
		'X-CoinPayments-Signature': '' // generated below 
	} 
}
 
// Convert payload to JSON string. 
const payloadMessage = request.data ? JSON.stringify(request.data) : ''; 
 
// Construct the unique request message. 
const message = `\ufeff${request.method}${request.url}${integration.clientId}${isoDate}${payloadMessage}`; 
 
// Hash the message using SHA-256, digesting in Base64. 
const signature = createHmac('sha256', integration.clientSecret) 
					.update(message) 
					.digest('base64'); 
 
// Set request header. 
request.headers['X-CoinPayments-Signature'] = signature; 
 
// Send API request. 
axios(request) 
	.then((response) => console.log(response.data))
	.catch((err) => console.log(`Error code: ${err.status}`));