X-Platform-ID– your API keyX-Signature– generated HMAC-SHA256 signature of the request
Canonical String Format
To generate a valid signature, you need to build a canonical string using the following format:METHOD + PATH + QUERY + BODY_HASH
Definitions
METHOD: HTTP method (e.g., GET, POST, PUT) PATH: API path only (e.g., /api/platform/users/create) QUERY: Raw query string (e.g., ?id=123), or empty if none BODY_HASH: SHA256 hex digest of the raw request body (for POST, PUT, etc.)Example Input
Method: POST
Path: /api/platform/users/create
Query: ?isExample=true&version=1.0.5
Body:
{
"name": "John Doe",
"email": "john@example.com",
"phone": "9876543210",
"phone_country_code": "+91"
}
Signature Generation Examples
const crypto = require('crypto');
const method = 'POST';
const path = '/api/platform/users/create';
const query = '?isExample=true&version=1.0.5';
const body = JSON.stringify({
name: 'John Doe',
email: 'john@example.com',
phone: '9876543210',
phone_country_code: '+91'
});
const bodyHash = crypto.createHash('sha256').update(body).digest('hex');
const canonicalString = `${method}${path}${query}${bodyHash}`;
const signature = crypto
.createHmac('sha256', 'your_platform_secret_key')
.update(canonicalString)
.digest('hex');
console.log('X-Signature:', signature);
import hashlib
import hmac
method = "POST"
path = "/api/platform/users/create"
query = "?isExample=true&version=1.0.5"
body = '{"name": "John Doe", "email": "john@example.com", "phone": "9876543210", "phone_country_code": "+91"}'
body_hash = hashlib.sha256(body.encode('utf-8')).hexdigest()
canonical_string = method + path + query + body_hash
secret_key = b'your_platform_secret_key'
signature = hmac.new(secret_key, canonical_string.encode('utf-8'), hashlib.sha256).hexdigest()
print("X-Signature:", signature)
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
)
func main() {
method := "POST"
path := "/api/platform/users/create"
query := "?isExample=true&version=1.0.5"
body := `{"name": "John Doe", "email": "john@example.com", "phone": "9876543210", "phone_country_code": "+91"}`
bodyHash := sha256.Sum256([]byte(body))
canonical := method + path + query + hex.EncodeToString(bodyHash[:])
secret := []byte("your_platform_secret_key")
h := hmac.New(sha256.New, secret)
h.Write([]byte(canonical))
signature := hex.EncodeToString(h.Sum(nil))
fmt.Println("X-Signature:", signature)
}
<?php
$method = 'POST';
$path = '/api/platform/users/create';
$query = '?isExample=true&version=1.0.5';
$body = json_encode([
'name' => 'John Doe',
'email' => 'john@example.com',
'phone' => '9876543210',
'phone_country_code' => '+91'
]);
$bodyHash = hash('sha256', $body);
$canonical = $method . $path . $query . $bodyHash;
$secretKey = 'your_platform_secret_key';
$signature = hash_hmac('sha256', $canonical, $secretKey);
echo "X-Signature: $signature";
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.util.Formatter;
public class SignatureGenerator {
public static void main(String[] args) throws Exception {
String method = "POST";
String path = "/api/platform/users/create";
String query = "?isExample=true&version=1.0.5";
String body = "{\"name\": \"John Doe\", \"email\": \"john@example.com\", \"phone\": \"9876543210\", \"phone_country_code\": \"+91\"}";
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] bodyHashBytes = md.digest(body.getBytes("UTF-8"));
StringBuilder bodyHash = new StringBuilder();
for (byte b : bodyHashBytes) {
bodyHash.append(String.format("%02x", b));
}
String canonical = method + path + query + bodyHash.toString();
String secret = "your_platform_secret_key";
SecretKeySpec keySpec = new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256");
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(keySpec);
byte[] hmacBytes = mac.doFinal(canonical.getBytes("UTF-8"));
Formatter formatter = new Formatter();
for (byte b : hmacBytes) {
formatter.format("%02x", b);
}
System.out.println("X-Signature: " + formatter.toString());
formatter.close();
}
}
require 'openssl'
require 'json'
require 'digest'
method = 'POST'
path = '/api/platform/users/create'
query = '?isExample=true&version=1.0.5'
body = {
name: "John Doe",
email: "john@example.com",
phone: "9876543210",
phone_country_code: "+91"
}.to_json
body_hash = Digest::SHA256.hexdigest(body)
canonical = method + path + query + body_hash
secret = 'your_platform_secret_key'
signature = OpenSSL::HMAC.hexdigest("SHA256", secret, canonical)
puts "X-Signature: #{signature}"
Complete API Call Examples
Once the signature is generated, use it in the X-Signature header as shown below:curl -X POST "https://<environment>/api/platform/users/create?isExample=true&version=1.0.5" \
-H "Content-Type: application/json" \
-H "X-Platform-ID: YOUR_API_KEY" \
-H "X-Signature: GENERATED_SIGNATURE" \
-d '{
"name": "John Doe",
"email": "john@example.com",
"phone": "9876543210",
"phone_country_code": "+91"
}'
const axios = require('axios');
const crypto = require('crypto');
const apiKey = 'YOUR_API_KEY';
const secretKey = 'your_platform_secret_key';
const apiPath = '/api/platform/users/create';
const query = '?isExample=true&version=1.0.5';
const url = 'https://<environment>' + apiPath;
const body = {
name: 'John Doe',
email: 'john@example.com',
phone: '9876543210',
phone_country_code: '+91'
};
const method = 'POST';
const bodyHash = crypto.createHash('sha256').update(JSON.stringify(body)).digest('hex');
const canonical = method + apiPath + query + bodyHash;
const signature = crypto
.createHmac('sha256', secretKey)
.update(canonical)
.digest('hex');
axios.post(url, body, {
headers: {
'Content-Type': 'application/json',
'X-Platform-ID': apiKey,
'X-Signature': signature
}
})
.then(res => console.log(res.data))
.catch(err => console.error(err.response?.data || err.message));
import hashlib
import hmac
import requests
import json
api_key = 'YOUR_API_KEY'
secret_key = b'your_platform_secret_key'
api_path = '/api/platform/users/create'
query = '?isExample=true&version=1.0.5'
url = 'https://<environment>' + api_path
body = {
"name": "John Doe",
"email": "john@example.com",
"phone": "9876543210",
"phone_country_code": "+91"
}
body_str = json.dumps(body)
body_hash = hashlib.sha256(body_str.encode()).hexdigest()
canonical = 'POST' + api_path + query + body_hash
signature = hmac.new(secret_key, canonical.encode(), hashlib.sha256).hexdigest()
headers = {
'Content-Type': 'application/json',
'X-Platform-ID': api_key,
'X-Signature': signature
}
response = requests.post(url, data=body_str, headers=headers)
print(response.status_code, response.text)
package main
import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
"io/ioutil"
"net/http"
)
func main() {
apiKey := "YOUR_API_KEY"
secretKey := "your_platform_secret_key"
apiPath := "/api/platform/users/create"
query := "?isExample=true&version=1.0.5"
url := "https://<environment>" + apiPath
body := `{"name":"John Doe","email":"john@example.com","phone":"9876543210","phone_country_code":"+91"}`
bodyHash := sha256.Sum256([]byte(body))
canonical := "POST" + apiPath + query + hex.EncodeToString(bodyHash[:])
h := hmac.New(sha256.New, []byte(secretKey))
h.Write([]byte(canonical))
signature := hex.EncodeToString(h.Sum(nil))
req, err := http.NewRequest("POST", url, bytes.NewBuffer([]byte(body)))
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-Platform-ID", apiKey)
req.Header.Set("X-Signature", signature)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
respBody, _ := ioutil.ReadAll(resp.Body)
fmt.Println("Status:", resp.Status)
fmt.Println("Response:", string(respBody))
}
<?php
$apiKey = 'YOUR_API_KEY';
$secretKey = 'your_platform_secret_key';
$apiPath = '/api/platform/users/create';
$query = '?isExample=true&version=1.0.5';
$url = 'https://<environment>' . $apiPath;
$body = json_encode([
'name' => 'John Doe',
'email' => 'john@example.com',
'phone' => '9876543210',
'phone_country_code' => '+91'
]);
$bodyHash = hash('sha256', $body);
$canonical = 'POST' . $apiPath . $query . $bodyHash;
$signature = hash_hmac('sha256', $canonical, $secretKey);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'X-Platform-ID: ' . $apiKey,
'X-Signature: ' . $signature
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
if ($response === false) {
echo 'Curl error: ' . curl_error($ch);
} else {
echo 'Response: ' . $response;
}
curl_close($ch);
import java.io.*;
import java.net.*;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
public class PaywintAPI {
public static void main(String[] args) throws Exception {
String apiKey = "YOUR_API_KEY";
String secretKey = "your_platform_secret_key";
String apiPath = "/api/platform/users/create";
String query = "?isExample=true&version=1.0.5";
String url = "https://<environment>" + apiPath;
String body = "{\"name\": \"John Doe\", \"email\": \"john@example.com\", \"phone\": \"9876543210\", \"phone_country_code\": \"+91\"}";
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] hash = md.digest(body.getBytes("UTF-8"));
StringBuilder bodyHash = new StringBuilder();
for (byte b : hash) bodyHash.append(String.format("%02x", b));
String canonical = "POST" + apiPath + query + bodyHash.toString();
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secretKey.getBytes("UTF-8"), "HmacSHA256"));
byte[] hmac = mac.doFinal(canonical.getBytes("UTF-8"));
StringBuilder signature = new StringBuilder();
for (byte b : hmac) signature.append(String.format("%02x", b));
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("X-Platform-ID", apiKey);
conn.setRequestProperty("X-Signature", signature.toString());
try (OutputStream os = conn.getOutputStream()) {
os.write(body.getBytes("UTF-8"));
}
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = br.readLine()) != null) System.out.println(line);
}
}
require 'uri'
require 'net/http'
require 'json'
require 'openssl'
require 'digest'
api_key = 'YOUR_API_KEY'
secret_key = 'your_platform_secret_key'
api_path = '/api/platform/users/create'
query = '?isExample=true&version=1.0.5'
url = URI("https://<environment>#{api_path}")
body = {
name: 'John Doe',
email: 'john@example.com',
phone: '9876543210',
phone_country_code: '+91'
}.to_json
body_hash = Digest::SHA256.hexdigest(body)
canonical = "POST" + api_path + query + body_hash
signature = OpenSSL::HMAC.hexdigest('sha256', secret_key, canonical)
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request['Content-Type'] = 'application/json'
request['X-Platform-ID'] = api_key
request['X-Signature'] = signature
request.body = body
response = http.request(request)
puts "Status: #{response.code}"
puts "Response: #{response.body}"
Alternatively, you can use the static signature in the sandbox environment:
8b3cb99a4b8e24fc7e01d0db635e2e47b80818144fe51400c6c6ae3ecbc84f47Best Practices
- Keep your API Key and Secret Key secure — never expose them on the client side
- Always use HTTPS to protect the signature and payload
- Regenerate the signature for every request; it’s not reusable
Need help? Reach out to support@paywint.com

