.agents/skills/p2p/references/authentication.md
All P2P personal order endpoints (SAPI) require HMAC SHA256 signed requests.
https://api.binance.com
X-MBX-APIKEY: your_api_keyUser-Agent: binance-wallet/1.0.0 (Skill)DO NOT sort parameters - SAPI keeps original insertion order (different from standard Binance API).
Correct approach for SAPI:
page=1&rows=20&recvWindow=60000×tamp=1710460800000Wrong approach (standard Binance API only):
Include all parameters plus timestamp (current Unix time in milliseconds):
timestamp=1234567890123
Optional: Add recvWindow (default 60000ms for P2P endpoints) for timestamp tolerance.
Before generating the signature, percent-encode all parameter names and values using UTF-8 encoding according to RFC 3986.
Unreserved characters that must not be encoded: A-Z a-z 0-9 - _ . ~
symbol=这是测试币456Percent-encoded:
symbol=%E8%BF%99%E6%98%AF%E6%B5%8B%E8%AF%95%E5%B8%81456
Important: The exact encoded query string must be used for both signing and the HTTP request.
Generate the HMAC SHA256 signature from the encoded query string using your secret key:
# Example using openssl
echo -n "page=1&rows=20&recvWindow=60000×tamp=1234567890123" | \
openssl dgst -sha256 -hmac "your_secret_key"
Add signature parameter to the query string:
page=1&rows=20&recvWindow=60000×tamp=1234567890123&signature=abc123...
Include required headers:
X-MBX-APIKEY: Your API keyUser-Agent: binance-wallet/1.0.0 (Skill)#!/bin/bash
API_KEY="your_api_key"
SECRET_KEY="your_secret_key"
BASE_URL="https://api.binance.com"
# Get current timestamp
TIMESTAMP=$(date +%s000)
# Build query string (without signature)
# CRITICAL: Keep parameter order, do NOT sort
QUERY="page=1&rows=20&recvWindow=60000×tamp=${TIMESTAMP}"
# Generate signature
SIGNATURE=$(echo -n "$QUERY" | openssl dgst -sha256 -hmac "$SECRET_KEY" | cut -d' ' -f2)
# Make request
curl -X GET \
"${BASE_URL}/sapi/v1/c2c/orderMatch/listUserOrderHistory?${QUERY}&signature=${SIGNATURE}" \
-H "X-MBX-APIKEY: ${API_KEY}" \
-H "User-Agent: binance-wallet/1.0.0 (Skill)"