HMAC-SHA256 Authentication
High-security authentication for server-side integration
For server-side integration scenarios requiring higher security than API Key. For everyday use with tools like Claude Code, API Key authentication is sufficient.
Authentication Flow & Request Headers
Authentication Flow:
- Obtain
appIdandappSecret(select "Other" scenario when applying) - Build the signature string
- Sign it with
appSecretusing HMAC-SHA256 - Include the authentication info in request headers
Request Headers:
| Header | Description |
|---|---|
X-App-Id | Application ID |
X-Timestamp | Unix timestamp (seconds), valid for 5 minutes |
X-Nonce | Random string to prevent replay attacks — must be unique per request |
Authorization | HMAC-SHA256 {signature} |
Signature Computation
Signature string format (fields joined with newline \n):
{HTTP_METHOD}\n{PATH}\n{TIMESTAMP}\n{NONCE}\n{APP_ID}Field Descriptions:
| Field | Description | Example |
|---|---|---|
HTTP_METHOD | Request method (uppercase) | POST |
PATH | Request path (no domain or query) | /chat/completions |
TIMESTAMP | Current Unix timestamp (seconds) | 1706745600 |
NONCE | 32-char random hex string | a1b2c3d4e5f67890abcdef1234567890 |
APP_ID | Application ID | app_xxxxx |
Steps:
- Concatenate the signature string using the format above (use actual newline characters
\n, not literal backslash-n) - Compute HMAC-SHA256 using
appSecretas the key - Convert the result to a lowercase hexadecimal string
Code Examples
Node.js
import { createHmac, randomBytes } from "crypto"
const APP_ID = "<your-app-id>"
const APP_SECRET = "<your-app-secret>"
const BASE_URL = "https://tokenhub.piegateway.me"
function computeSignature(
method: string,
path: string,
timestamp: number,
nonce: string,
appId: string,
appSecret: string,
): string {
const signatureString = `${method}\n${path}\n${timestamp}\n${nonce}\n${appId}`
return createHmac("sha256", appSecret).update(signatureString).digest("hex")
}
function generateAuthHeaders(method: string, path: string) {
const timestamp = Math.floor(Date.now() / 1000)
const nonce = randomBytes(16).toString("hex")
const signature = computeSignature(method, path, timestamp, nonce, APP_ID, APP_SECRET)
return {
"X-App-Id": APP_ID,
"X-Timestamp": timestamp.toString(),
"X-Nonce": nonce,
Authorization: `HMAC-SHA256 ${signature}`,
"Content-Type": "application/json",
}
}
// Usage example
const path = "/chat/completions"
const headers = generateAuthHeaders("POST", path)
const response = await fetch(`${BASE_URL}${path}`, {
method: "POST",
headers,
body: JSON.stringify({
model: "claude-haiku-4-5",
messages: [{ role: "user", content: "Hello" }],
max_tokens: 100,
}),
})
const result = await response.json()
console.log(result)Bash
#!/bin/bash
APP_ID="<your-app-id>"
APP_SECRET="<your-app-secret>"
BASE_URL="https://tokenhub.piegateway.me"
METHOD="POST"
API_PATH="/chat/completions"
TIMESTAMP=$(date +%s)
NONCE=$(openssl rand -hex 16)
# Build signature string
SIGNATURE_STRING=$(printf "%s\n%s\n%s\n%s\n%s" "$METHOD" "$API_PATH" "$TIMESTAMP" "$NONCE" "$APP_ID")
# Compute HMAC-SHA256 signature (compatible with macOS and Linux)
SIGNATURE=$(echo -n "$SIGNATURE_STRING" | openssl dgst -sha256 -hmac "$APP_SECRET" | sed 's/^.*= //')
curl -X POST "{BASE_URL}{API_PATH}" \
-H "X-App-Id: ${APP_ID}" \
-H "X-Timestamp: ${TIMESTAMP}" \
-H "X-Nonce: ${NONCE}" \
-H "Authorization: HMAC-SHA256 ${SIGNATURE}" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-haiku-4-5",
"messages": [{"role": "user", "content": "Hello"}],
"max_tokens": 100
}'WebSocket Authentication
WebSocket connections also support HMAC-SHA256 signature authentication:
Method 1: Headers (Recommended)
const ws = new WebSocket("wss://tokenhub.piegateway.me/ws/...", {
headers: generateAuthHeaders("GET", "/ws/..."),
})Method 2: Query Parameters (for browser environments)
const params = new URLSearchParams({
"X-App-Id": APP_ID,
"X-Timestamp": timestamp.toString(),
"X-Nonce": nonce,
Authorization: `HMAC-SHA256 ${signature}`,
})
const ws = new WebSocket(`wss://tokenhub.piegateway.me/ws/...?${params}`)Security Constraints & Error Codes
Security Constraints:
| Constraint | Description |
|---|---|
| Timestamp validity | 5 minutes (300 seconds) — expired requests will be rejected |
| Nonce replay guard | Same nonce can be used at most 3 times, expires after 300s |
| Signature case | Signature must be a lowercase hexadecimal string |
HMAC Authentication Error Codes:
| Status | Error Type | Description |
|---|---|---|
| 401 | missing_auth_headers | Required authentication headers are missing |
| 401 | invalid_timestamp | Timestamp expired (more than 5 minutes) |
| 401 | nonce_reused | Nonce has been reused (replay protection) |
| 401 | invalid_app | appId does not exist |
| 401 | invalid_signature | Signature verification failed — check appSecret and string format |
| 403 | app_disabled | Application has been disabled |