Request Signing
How the canonical message is built, and the two mistakes that break it.
POST and DELETE carry an X-Signature header: an HMAC-SHA256 of a canonical message, keyed with your API key.
Canonical message
# hash of "" when there is no body
body_sha256 = SHA256(raw_request_body_bytes)
message = "{METHOD}\n{PATH}\n{TIMESTAMP}\n{BODY_SHA256}"
signature = HMAC-SHA256(key=api_key, msg=message).hexdigest()
Two things to get right
PATH is the full path (/ext/v1/bbps/bill/pay, not /bill/pay). And sign the exact bytes you transmit — serialise the body once, hash that buffer, send that same buffer. Re-serialising between signing and sending changes the hash and the request is rejected.
Worked example
For POST /ext/v1/dmt/charges with body {"amount": 1000.00} at timestamp 1785312000, the message that gets signed is these four lines exactly — no trailing newline:
POST /ext/v1/dmt/charges 1785312000 61b1a5a2b2b4be2d0e5e6dc1cf0e5a9a1b3f0d4d5e2a7c8b9f0a1b2c3d4e5f60
Pick your language in the Request panel on any endpoint page — each sample computes this signature for that exact endpoint, ready to paste.