Authentication
Every merchant API request carries an HMAC-SHA256 signature. There is no bearer token: possession of the secret is proven per request, so a captured request cannot be replayed against a different path, method or body.
If you use @flowpayra/sdk this is handled for you. Read on if you are signing
from another language.
Headers
Section titled “Headers”| Header | Value |
|---|---|
x-api-key |
Your key id |
x-timestamp |
Unix seconds |
x-nonce |
Unique per request |
x-signature |
Lowercase hex HMAC-SHA256 |
The timestamp must be within 300 seconds of server time. A nonce is accepted once — replaying it fails even inside the window.
Canonical string
Section titled “Canonical string”Six fields joined by newlines, in this order:
{key_id}\n{timestamp}\n{nonce}\n{METHOD}\n{path_and_query}\n{sha256_hex(body)}Two details cause most integration failures:
path_and_queryincludes the query string. Sign/v1/payments?limit=10, not/v1/payments. The signature covers the query so it cannot be rewritten in transit.- The body hash is always present. For a request with no body, hash the empty
string —
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.
The signature is hex(hmac_sha256(secret_utf8, canonical_utf8)).
Verify your implementation
Section titled “Verify your implementation”This vector is one of the shared fixtures the server and the TypeScript SDK are both tested against. If you reproduce it byte for byte, your signing is correct.
secret sk_demo_secretkey_id ak_demotimestamp 1700000000nonce 0f1e2d3c4b5a69788796a5b4c3d2e1f0method POSTpath /v1/paymentsbody {"merchant_order_no":"order-1","quotes":{"cur_usdc":{"amount":"100","chain_ids":["chain_base"]}}}
body_sha256 4d86aac4754077a8f1e255cae0c7d87cae3c9ef1d5dd71d14d99c17d77833ca1signature 8daf2e606f510f1df1a1efe39761a9ac561330ce598a3b9eb88760941eaba128Key scopes
Section titled “Key scopes”A key is either read or trade. A read key is rejected with 403 on any
method other than GET, so a key that only needs to poll payment status cannot
create or cancel one. Issue the narrowest scope that does the job.