Skip to main content
Server-to-server Blink endpoints — whitelisting domains and the deposit & user reporting APIs — are authenticated with a signed X-Merchant-Authorization header. It is a signature-based identity credential that proves “I am merchant X”. It is not a fund-movement authorization — it only proves identity, so the same credential safely authenticates read endpoints and identity-scoped writes alike. You build it on your server with the same ECDSA P-256 private key you use for your signer endpoint. Blink stores only your public key (submitted during Merchant Registration), so a leaked credential cannot be used to recover your key.
Never expose your merchant private key in client code. Always build the X-Merchant-Authorization header on your server.

Where it’s used

The Deposit SDK signer endpoint uses the same signing algorithm, but its payload additionally binds the payment parameters (amount, address, token, …). The header credential below is the identity-only variant: its payload carries just a version and a fresh timestamp.

The header

The X-Merchant-Authorization value is a base64-encoded JSON envelope:

Build the header

1

Build the payload

A small JSON object with a version and a fresh timestamp:
Generate signatureTimestamp per request — Blink enforces a 15-minute max signature age.
2

Base64url-encode the payload

Encode the JSON string to base64url (no padding) — this exact string is what you sign.
3

Sign the encoded string

Sign the base64url payload string with ECDSA P-256 + SHA-256, then base64url-encode the signature. See Key Generation for the key and the Signer Endpoint for the identical signing mechanics.
4

Assemble and base64-encode the envelope

Put { merchantId, payload, signature } into JSON, base64-encode the whole thing, and send it as the X-Merchant-Authorization header.
Example (Node.js) — reuses the helpers from your signer endpoint:
Send it on every request:

Freshness

Blink validates the payload’s timestamp server-side, so you don’t manage TTLs yourself:
  • signatureTimestamp (recommended) — must be within the last 15 minutes and not in the future.
  • expiresAt (optional alternative) — an explicit expiry; rejected if already past or more than 1 hour in the future.
Include at least one. Because the credential is not bound to the individual request, treat it like a short-lived bearer token: always send it over HTTPS and regenerate it per request from the fresh timestamp.

Error responses

All envelope-authenticated endpoints share these auth failures (in the standard Error shape):