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.
Where it’s used
| Endpoint | Method | Purpose |
|---|---|---|
/v1/merchant-users | GET | List your Blink users / look one up by wallet. |
/v1/merchant-deposits | GET | List deposits into your platform. |
/v1/merchant-domains | POST | Whitelist an additional origin. |
amount, address, token, …). The header
credential below is the identity-only variant: its payload carries just a version and a fresh timestamp.
The header
TheX-Merchant-Authorization value is a base64-encoded JSON envelope:
Build the header
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.Base64url-encode the payload
Encode the JSON string to base64url (no padding) — this exact string is what you sign.
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.
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.
Error responses
All envelope-authenticated endpoints share these auth failures (in the standardError shape):
| Code | Meaning |
|---|---|
400 | The X-Merchant-Authorization header is missing JSON / not base64 / malformed. |
401 MERCHANT_AUTHORIZATION_MISSING | The X-Merchant-Authorization header is absent. |
403 MERCHANT_NOT_REGISTERED / MERCHANT_NOT_ACTIVE | The merchant is unknown or not yet approved. |
422 MERCHANT_AUTHORIZATION_EXPIRED | The signatureTimestamp/expiresAt is stale or expired. |
422 MERCHANT_SIGNATURE_TIMESTAMP_INVALID | The timestamp is malformed or in the future. |
422 MERCHANT_SIGNATURE_INVALID | The signature does not verify against your registered public key. |