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

EnvironmentDomain
Testhttp://120.25.215.223
Productionhttps://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

EnvironmentURL
TestPOST http://120.25.215.223/restapi/price/changelog
ProductionPOST https://www.waveshare.com/restapi/price/changelog

2.1 Request Parameters

ParameterRequiredTypeDescription
app_keyYesstringClient identity assigned by Waveshare, e.g. wsapi_demo
timestampYesintUnix epoch timestamp (UTC) at request time; server verifies deviation ≤ 300 seconds
signYesstringRequest signature, see Section 4 for details
start_dateNostringStart date, format YYYY-MM-DD; default is 7 days ago
end_dateNostringEnd date, format YYYY-MM-DD; default is today
pageNointPage number, starting from 1; default is 1
page_sizeNointNumber of records per page; default is 20, maximum is 100
skuNostringFilter by exact SKU (optional)

2.2 Response Parameters

Success Response (code = 0)
FieldTypeDescription
codeintReturn code; 0 indicates success
msgstringReturn message
server_timeintCurrent server Unix timestamp
data.pageintCurrent page number
data.page_sizeintRecords per page
data.totalintTotal number of matching records
data.list[].skustringProduct SKU
data.list[].part_numberstringProduct part number
data.list[].retail_pricefloatRetail price (USD)
data.list[].distributor_pricefloat|nullDistributor price (USD). Returns a float under normal conditions; returns null when the discount is cancelled — refer to the desc field
data.list[].descstring|nullDescription field. Returns discount_cancelled when distributor_price is null due to discount cancellation; otherwise returns null
data.list[].currencystringCurrency unit, fixed as USD
data.list[].changed_atstringPrice 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
FieldTypeDescription
codeintError code
msgstringError description
server_timeintCurrent server Unix timestamp
Error Code Table
codeMeaning
0Success
40001Missing required parameter
40101app_key does not exist or is disabled
40102Timestamp expired or clock skew exceeds 300 seconds
40104Signature error
42901Rate limit exceeded (per app_key)
50000Internal 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

EnvironmentURL
TestPOST http://120.25.215.223/restapi/price/history
ProductionPOST https://www.waveshare.com/restapi/price/history

3.1 Request Parameters

ParameterRequiredTypeDescription
app_keyYesstringClient identity assigned by Waveshare
timestampYesintUnix epoch timestamp (UTC) at request time
signYesstringRequest signature, see Section 4 for details
skuYesstringProduct SKU

3.2 Response Parameters

Success Response (code = 0)
FieldTypeDescription
codeintReturn code; 0 indicates success
msgstringReturn message
server_timeintCurrent server Unix timestamp
data.skustringProduct SKU
data.history[].retail_pricefloatRetail price (USD)
data.history[].distributor_pricefloat|nullDistributor price (USD). Returns a float under normal conditions; returns null when the discount is cancelled — refer to the desc field
data.history[].descstring|nullDescription field. Returns discount_cancelled when distributor_price is null due to discount cancellation; otherwise returns null
data.history[].currencystringCurrency unit, fixed as USD
data.history[].changed_atstringPrice 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

  1. Prepare parameters: Collect all request parameters except sign itself.
  2. Filter empty values: Remove parameters whose values are empty strings or null.
  3. Sort lexicographically: Sort parameters by their keys in ascending ASCII order.
  4. 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.
  5. Compute the signature: Sign the concatenated string using the HMAC-SHA256 algorithm with the app_secret as the key.
  6. 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

  1. Clock Synchronization: Ensure that your server time is within 300 seconds of UTC; otherwise, requests will be rejected.
  2. Rate Limiting: Each app_key has an independent rate limit (default 60 requests/minute). Exceeding this limit will return a 42901 error.
  3. Data Range: The span between start_date and end_date should not exceed 90 days to avoid excessively large responses.
  4. HTTPS Required: The production environment supports HTTPS only; HTTP requests will be rejected.
  5. Credential Security: Keep your app_secret safe. Do not disclose it to any third party.