CheapEmail Open API - AI integration contract Canonical documentation: https://docs.cheapemail.cc/ Base site: https://cheapemail.cc API prefix: /api/v1/upstream API access application: https://cheapemail.cc/me/api ACCESS Apply in the CheapEmail user dashboard at the URL above. API_KEY and API_SECRET can be generated only after the application is approved. GOAL Implement the smallest purchasing flow. The caller provides only: - sku_code: string - quantity: integer >= 1 Do not ask the caller for sku_id. Do not add other order fields to the basic flow. AUTHENTICATION Send these headers on every API request: - Dujiao-Next-Api-Key: API_KEY - Dujiao-Next-Timestamp: Unix timestamp in seconds - Dujiao-Next-Signature: lowercase hexadecimal signature - Content-Type: application/json Build the four-line signing string exactly as: METHOD\nPATH\nTIMESTAMP\nBODY_MD5 Conversions and algorithm: 1. body_bytes = the exact bytes sent as the request body, or empty bytes for no body. 2. body_md5 = lowercase hexadecimal MD5(body_bytes). 3. sign_string = uppercase METHOD + newline + PATH + newline + TIMESTAMP + newline + body_md5. 4. secret_bytes = UTF8(API_SECRET). 5. message_bytes = UTF8(sign_string). 6. signature = HEX_LOWER(HMAC-SHA256(key=secret_bytes, message=message_bytes)). Do not hash API_SECRET before using it as the HMAC key. MD5 applies only to body_bytes. The MD5 of an empty body is d41d8cd98f00b204e9800998ecf8427e. PATH excludes the domain and query string. SKU DISCOVERY 1. GET /api/v1/upstream/products?page=1&page_size=100. 2. Sign only the path /api/v1/upstream/products, without the query string. 3. Continue page by page until accumulated items >= total or the returned page is empty. 4. For every active SKU, associate skus[].sku_code with: - product title - product description - SKU price - stock_status - stock_quantity - skus[].id as internal sku_id 5. Present sku_code to the caller. Keep sku_id internal. SKU CONFIRMATION Before creating an order, show the caller the matching sku_code, product title, specification, description, price, and stock status. Ask the caller to confirm the intended sku_code and quantity. Never guess a sku_code from a product name, and never create an order before confirmation when the caller has not already provided an exact sku_code. ORDER FLOW 1. Find an exact sku_code match in the current product data. 2. Reject a missing, inactive, or out_of_stock SKU before ordering. 3. Serialize and send only this JSON body to POST /api/v1/upstream/orders: {"sku_id":11,"quantity":2} 4. Use the exact serialized bytes for body MD5, signature calculation, and the HTTP body. 5. Read order_id and order_no from the successful response. 6. Poll GET /api/v1/upstream/orders/{order_id} until status is delivered or completed. 7. Stop with an error if status is canceled or the wait times out. FULFILLMENT PAYLOAD The purchased data is order.fulfillment.payload. In JSON, a payload such as "data-1\ndata-2" represents two lines after JSON decoding: data-1 data-2 Each non-empty line is one purchased data item. Support both real newline characters and literal backslash sequences \n, \r\n, and \r. Remove empty lines. Save UTF-8 text to: orders/order_.txt Sanitize order_no for filesystem use. The saved file must contain exactly one purchased item per line. REFERENCE IMPLEMENTATIONS Python source: https://docs.cheapemail.cc/downloads/test.py Python dependencies: https://docs.cheapemail.cc/downloads/requirements.txt Go source: https://docs.cheapemail.cc/downloads/dujiao_client.go OpenAPI: https://docs.cheapemail.cc/openapi.yaml Python usage: python test.py python test.py skus python test.py order SKU-1 2 Go usage: go run dujiao_client.go -action skus go run dujiao_client.go -action order -sku-code SKU-1 -quantity 2 -wait SECURITY Keep API_SECRET in a local script, environment variable, or server-side secret store. Never expose it in browser JavaScript, URLs, logs, public repositories, or generated documentation.