Payload Signing
Payload signing is optional. Most accounts only need Authorization: Bearer <api_key>. If you want request-body signing enabled for your account, let us know and we can add it.
When enabled, use the HMAC secret from the Dashboard to sign the exact request body you send to Celar.
What to Send
Signed requests still use your normal API key:
Authorization: Bearer <api_key>
Content-Type: application/json
X-Signature: <hmac_sha256_signature>
X-Signature is not the secret itself. It is the hex HMAC-SHA256 digest of the raw JSON request body.
X-Signature = HMAC-SHA256(raw_request_body, hmac_secret)
Example
Use the exact same body string for both signing and sending.
import crypto from 'node:crypto';
const apiKey = process.env.CELAR_API_KEY;
const hmacSecret = process.env.CELAR_HMAC_SECRET;
const body = JSON.stringify({
customer_id: 'cr_70be275b878077ab',
amount: 200,
operationType: 'payin',
source: {
currency: 'USDC',
chain: 'baseSepolia',
description: 'Payment for Order #009',
reference: 'ref101',
},
});
const signature = crypto
.createHmac('sha256', hmacSecret)
.update(body)
.digest('hex');
await fetch('https://api.sandbox.celar.io/api/v1/payments/transfer', {
method: 'POST',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
'X-Signature': signature,
},
body,
});
Common Mistakes
- Do not put the HMAC secret directly in
X-Signature. - Do not sign a different JSON string than the one you send.
- Do not parse and re-stringify the body after signing.
- Do not confuse
X-Signaturewith the ratesignaturereturned by the Rates API or thewebhook-signatureheader on webhooks. - Keep the HMAC secret server-side. Do not expose it in browser code.