Waveshare API Documentation
This document is intended for third-party integrators (distributors, ERP systems, quoting platforms, etc.) and describes how to call the Waveshare API.
1. Environments
| Environment | Domain |
| Test | http://120.25.215.223 |
| Production | https://www.waveshare.com |
All API requests use the POST method. The request body is in JSON format with Content-Type: application/json.
2. Price Change List (priceloglist)
Retrieves a paginated list of products whose prices have changed within a specified time range.
Endpoint
| Environment | URL |
| Test | POST http://120.25.215.223/restapi/price/changelog |
| Production | POST https://www.waveshare.com/restapi/price/changelog |
2.1 Request Parameters
| Parameter | Required | Type | Description |
app_key | Yes | string | Client identity assigned by Waveshare, e.g. wsapi_demo |
timestamp | Yes | int | Unix epoch timestamp (UTC) at request time; server verifies deviation ≤ 300 seconds |
sign | Yes | string | Request signature, see Section 4 for details |
start_date | No | string | Start date, format YYYY-MM-DD; default is 7 days ago |
end_date | No | string | End date, format YYYY-MM-DD; default is today |
page | No | int | Page number, starting from 1; default is 1 |
page_size | No | int | Number of records per page; default is 20, maximum is 100 |
sku | No | string | Filter by exact SKU (optional) |
2.2 Response Parameters
Success Response (code = 0)
| Field | Type | Description |
code | int | Return code; 0 indicates success |
msg | string | Return message |
server_time | int | Current server Unix timestamp |
data.page | int | Current page number |
data.page_size | int | Records per page |
data.total | int | Total number of matching records |
data.list[].sku | string | Product SKU |
data.list[].part_number | string | Product part number |
data.list[].retail_price | float | Retail price (USD) |
data.list[].distributor_price | float|null | Distributor price (USD). Returns a float under normal conditions; returns null when the discount is cancelled — refer to the desc field |
data.list[].desc | string|null | Description field. Returns discount_cancelled when distributor_price is null due to discount cancellation; otherwise returns null |
data.list[].currency | string | Currency unit, fixed as USD |
data.list[].changed_at | string | Price change date, format YYYY-MM-DD |
Note: The API only returns fields visible to distributors on the Price Changelog page. Sensitive information such as cost prices and internal notes is excluded.
Error Response
| Field | Type | Description |
code | int | Error code |
msg | string | Error description |
server_time | int | Current server Unix timestamp |
Error Code Table
| code | Meaning |
| 0 | Success |
| 40001 | Missing required parameter |
| 40101 | app_key does not exist or is disabled |
| 40102 | Timestamp expired or clock skew exceeds 300 seconds |
| 40104 | Signature error |
| 42901 | Rate limit exceeded (per app_key) |
| 50000 | Internal server error |
2.3 Request Example
POST /restapi/price/changelog
Content-Type: application/json
{"app_key":"wsapi_demo","timestamp":1748083920,"start_date":"2026-03-10","end_date":"2026-03-21","page":1,"page_size":20,"sign":"7A1B2C3D4E5F6A7B8C9D0E1F2A3B4C5D6E7F8A9B0C1D2E3F4A5B6C7D8E9F0"}
2.4 Response Example
{
"code": 0,
"msg": "ok",
"server_time": 1748083920,
"data": {
"page": 1,
"page_size": 20,
"total": 57,
"list": [
{
"sku": "14865",
"part_number": "SIM7000E NB-IoT HAT",
"retail_price": 45.00,
"distributor_price": 37.13,
"desc": null,
"currency": "USD",
"changed_at": "2026-05-21"
},
{
"sku": "10451",
"part_number": "RP2040-Zero",
"retail_price": 5.99,
"distributor_price": null,
"desc": "discount_cancelled",
"currency": "USD",
"changed_at": "2026-05-21"
}
]
}
}
2.5 Error Response Example
{
"code": 40104,
"msg": "sign error",
"server_time": 1748083920,
"data": null
}
3. Single SKU Price History (pricehistory)
Retrieves the historical price change records for a specific product.
Endpoint
| Environment | URL |
| Test | POST http://120.25.215.223/restapi/price/history |
| Production | POST https://www.waveshare.com/restapi/price/history |
3.1 Request Parameters
| Parameter | Required | Type | Description |
app_key | Yes | string | Client identity assigned by Waveshare |
timestamp | Yes | int | Unix epoch timestamp (UTC) at request time |
sign | Yes | string | Request signature, see Section 4 for details |
sku | Yes | string | Product SKU |
3.2 Response Parameters
Success Response (code = 0)
| Field | Type | Description |
code | int | Return code; 0 indicates success |
msg | string | Return message |
server_time | int | Current server Unix timestamp |
data.sku | string | Product SKU |
data.history[].retail_price | float | Retail price (USD) |
data.history[].distributor_price | float|null | Distributor price (USD). Returns a float under normal conditions; returns null when the discount is cancelled — refer to the desc field |
data.history[].desc | string|null | Description field. Returns discount_cancelled when distributor_price is null due to discount cancellation; otherwise returns null |
data.history[].currency | string | Currency unit, fixed as USD |
data.history[].changed_at | string | Price change date, format YYYY-MM-DD |
3.3 Request Example
POST /restapi/price/history
Content-Type: application/json
{"app_key":"wsapi_demo","timestamp":1748083920,"sku":"10451","sign":"7A1B2C3D4E5F6A7B8C9D0E1F2A3B4C5D6E7F8A9B0C1D2E3F4A5B6C7D8E9F0"}
3.4 Response Example
{
"code": 0,
"msg": "ok",
"server_time": 1748083920,
"data": {
"sku": "10451",
"history": [
{
"retail_price": 5.99,
"distributor_price": 4.79,
"desc": null,
"currency": "USD",
"changed_at": "2026-05-21"
},
{
"retail_price": 6.99,
"distributor_price": null,
"desc": "discount_cancelled",
"currency": "USD",
"changed_at": "2026-05-14"
}
]
}
}
4. Authentication (HMAC-SHA256 Signature)
All API requests must include three authentication parameters: app_key, timestamp, and sign.
4.1 Signature Algorithm
- Prepare parameters: Collect all request parameters except
sign itself.
- Filter empty values: Remove parameters whose values are empty strings or
null.
- Sort lexicographically: Sort parameters by their keys in ascending ASCII order.
- Build the string to sign: Concatenate the sorted parameters as
key=value pairs separated by &. Keys and values must be URL-encoded per RFC 3986. Important: The signature is computed from the key-value pairs of the parameters, not from the JSON body string itself. Therefore, the signature algorithm remains unchanged regardless of the request body format.
- Compute the signature: Sign the concatenated string using the HMAC-SHA256 algorithm with the
app_secret as the key.
- Output: Convert the resulting signature to an uppercase hexadecimal string and use it as the
sign parameter value.
4.2 PHP Example
<?php
function ws_request($path, array $biz, $appKey, $appSecret)
{
// 1. Merge business and authentication parameters
$params = array_merge($biz, [
'app_key' => $appKey,
'timestamp' => time(),
]);
// 2. Filter empty values
foreach ($params as $k => $v) {
if ($v === '' || $v === null) unset($params[$k]);
}
// 3. Sort by key (ASCII ascending)
ksort($params);
// 4. URL-encode and concatenate key-value pairs
$pairs = [];
foreach ($params as $k => $v) {
$pairs[] = rawurlencode($k) . '=' . rawurlencode((string)$v);
}
$stringToSign = implode('&', $pairs);
// 5. Compute HMAC-SHA256 signature and convert to uppercase hex
$params['sign'] = strtoupper(hash_hmac('sha256', $stringToSign, $appSecret));
// 6. Send POST request (JSON body)
$url = 'http://120.25.215.223' . $path; // Test environment; for production, use https://www.waveshare.com
$body = json_encode($params);
$ctx = stream_context_create([
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/json\r\n"
. 'Content-Length: ' . strlen($body) . "\r\n",
'content' => $body,
'timeout' => 10,
'ignore_errors' => true,
],
]);
return json_decode(file_get_contents($url, false, $ctx), true);
}
// ===== Call priceloglist endpoint =====
$resp1 = ws_request('/restapi/price/changelog', [
'start_date' => '2026-03-10',
'end_date' => '2026-03-21',
'page' => 1,
'page_size' => 20,
], 'waveshare_demo', 'waveshare_demo_app_secret');
print_r($resp1);
// ===== Call pricehistory endpoint =====
$resp2 = ws_request('/restapi/price/history', [
'sku' => '10451',
], 'waveshare_demo', 'waveshare_demo_app_secret');
print_r($resp2);
4.3 Python Example
import hashlib
import hmac
import time
import urllib.parse
import requests
def ws_request(path, biz, app_key, app_secret):
# 1. Merge business and authentication parameters
params = {**biz, 'app_key': app_key, 'timestamp': int(time.time())}
# 2. Filter empty values
params = {k: v for k, v in params.items() if v != '' and v is not None}
# 3. Sort by key and URL-encode key-value pairs
sorted_items = sorted(params.items())
qs = urllib.parse.urlencode(sorted_items)
# 4. Compute HMAC-SHA256 signature and convert to uppercase hex
sign = hmac.new(app_secret.encode(), qs.encode(), hashlib.sha256).hexdigest().upper()
params['sign'] = sign
# 5. Send POST request (JSON body)
url = 'http://120.25.215.223' + path # Test environment; for production, use https://www.waveshare.com
return requests.post(url, json=params, timeout=10).json()
# ===== Call priceloglist endpoint =====
resp1 = ws_request(
'/restapi/price/changelog',
{'start_date': '2026-03-10', 'end_date': '2026-03-21', 'page': 1, 'page_size': 20},
'waveshare_demo', 'waveshare_demo_app_secret',
)
print(resp1)
# ===== Call pricehistory endpoint =====
resp2 = ws_request(
'/restapi/price/history',
{'sku': '10451'},
'waveshare_demo', 'waveshare_demo_app_secret',
)
print(resp2)
4.4 cURL Example (Manual Signature)
#!/bin/bash
# Note: This example requires you to construct the sign manually.
# In practice, use the SDK or a script to compute it automatically.
APP_KEY="waveshare_demo"
APP_SECRET="waveshare_demo_app_secret"
TIMESTAMP=$(date +%s)
# Construct the string to sign (concatenate app_key, timestamp, start_date, end_date, page, page_size)
# Note: The sign below is a placeholder; replace it with the actual computed signature.
# Call priceloglist endpoint (JSON body)
curl -s -X POST "http://120.25.215.223/restapi/price/changelog" \
-H "Content-Type: application/json" \
-d '{"app_key":"wsapi_demo","timestamp":'${TIMESTAMP}',"start_date":"2026-03-10","end_date":"2026-03-21","page":1,"page_size":20,"sign":"<computed_signature>"}'
5. Notes
- Clock Synchronization: Ensure that your server time is within 300 seconds of UTC; otherwise, requests will be rejected.
- Rate Limiting: Each
app_key has an independent rate limit (default 60 requests/minute). Exceeding this limit will return a 42901 error.
- Data Range: The span between
start_date and end_date should not exceed 90 days to avoid excessively large responses.
- HTTPS Required: The production environment supports HTTPS only; HTTP requests will be rejected.
- Credential Security: Keep your
app_secret safe. Do not disclose it to any third party.